考虑一个类型层次结构,其中基对象是非泛型的,但子类型是:
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"
Run Code Online (Sandbox Code Playgroud)
of
像这样使用运算符不会编译,因为它需要 object types。有效的是例如匹配特定类型,例如DerivedB[int]
,或使 proc 本身通用 in T
,这在传入 a 时毫无意义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()
Run Code Online (Sandbox Code Playgroud)
此解决方案不会增加对象的大小,并且不会在典型代码中引入任何运行时开销。
如果您不能修改继承层次结构(它可能是第三方库的一部分),则基于getTypeInfo
来自系统模块的proc有一个更复杂的解决方案。这个过程返回一个不透明的指针,可以用作类型的标识符。您必须在哈希表中注册所有派生类型及其标识符(您可以在程序开始时执行此操作),然后使用它对输入值的类型信息指针进行运行时检查过程
归档时间: |
|
查看次数: |
298 次 |
最近记录: |