如何将 Nim 的 `of` 运算符与泛型一起使用?
How to use Nim's `of` operator with generics?
考虑一个类型层次结构,其中基础对象是非泛型的,但子类型是:
type
TestBase = ref object of RootObj
DerivedA = ref object of TestBase
DerivedB[T] = ref object of TestBase
field: T
proc testProc(x: TestBase) =
if x of DerivedB: # <= what to do here
echo "it's a B!"
else:
echo "not a B"
像这样使用 of
运算符将无法编译,因为它 需要对象类型 。什么工作是例如匹配 DerivedB[int]
等特定类型,或者在 T
中使 proc 本身通用,这在传入 DerivedA
.
时毫无意义
有没有办法在不借助方法和动态调度的情况下通用地解决这个问题?
此处最简单的解决方案是为所有泛型派生类型引入虚拟基类型,其唯一目的是协助进行此类检查。这是一个例子:
type
TestBase = ref object of RootObj
DerivedA = ref object of TestBase
# I'm using illustrative names here
# You can choose something more sensible
DerivedDetector = ref object of TestBase
DerivedB[T] = ref object of DerivedDetector
field: T
proc testProc(x: TestBase) =
if x of DerivedDetector: # This will be true for all derived types
echo "it's a B!"
else:
echo "not a B"
testProc DerivedB[int](field: 10)
testProc DerivedA()
此解决方案不会增加对象的大小,并且不会在典型代码中引入任何 运行 次开销。
如果您无法修改继承层次结构(它可能是第三方库的一部分),则有一个基于系统模块中的 getTypeInfo
proc 的更复杂的解决方案。此过程 returns 一个不透明指针,可用作该类型的标识符。您必须在散列 table 中注册所有派生类型及其标识符(您可以在程序开始时执行此操作),然后使用它对类型进行 运行-时间检查-过程中输入值的信息指针。
考虑一个类型层次结构,其中基础对象是非泛型的,但子类型是:
type
TestBase = ref object of RootObj
DerivedA = ref object of TestBase
DerivedB[T] = ref object of TestBase
field: T
proc testProc(x: TestBase) =
if x of DerivedB: # <= what to do here
echo "it's a B!"
else:
echo "not a B"
像这样使用 of
运算符将无法编译,因为它 需要对象类型 。什么工作是例如匹配 DerivedB[int]
等特定类型,或者在 T
中使 proc 本身通用,这在传入 DerivedA
.
有没有办法在不借助方法和动态调度的情况下通用地解决这个问题?
此处最简单的解决方案是为所有泛型派生类型引入虚拟基类型,其唯一目的是协助进行此类检查。这是一个例子:
type
TestBase = ref object of RootObj
DerivedA = ref object of TestBase
# I'm using illustrative names here
# You can choose something more sensible
DerivedDetector = ref object of TestBase
DerivedB[T] = ref object of DerivedDetector
field: T
proc testProc(x: TestBase) =
if x of DerivedDetector: # This will be true for all derived types
echo "it's a B!"
else:
echo "not a B"
testProc DerivedB[int](field: 10)
testProc DerivedA()
此解决方案不会增加对象的大小,并且不会在典型代码中引入任何 运行 次开销。
如果您无法修改继承层次结构(它可能是第三方库的一部分),则有一个基于系统模块中的 getTypeInfo
proc 的更复杂的解决方案。此过程 returns 一个不透明指针,可用作该类型的标识符。您必须在散列 table 中注册所有派生类型及其标识符(您可以在程序开始时执行此操作),然后使用它对类型进行 运行-时间检查-过程中输入值的信息指针。