2017-02-22 5 views
1

は、ベースオブジェクトが非ジェネリックで型階層を、考えてみたが、サブタイプは次のとおりです。Nimの `of`演算子をジェネリックで使うには?

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自体を汎用的にする。

メソッドと動的ディスパッチに頼らずに一般的にこの問題を解決する方法はありますか?

答えて

4

ここで最も簡単な解決策は、一般的な派生型のすべてにダミーの基本型を導入することです。この唯一の目的は、このようなチェックを支援することです。ここには例があります:

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に基づいたはるかに複雑な解決策があります。このprocは、その型の識別子として使用できる不透明なポインタを返します。派生したすべての型を識別子でハッシュテーブルに登録する必要があります(プログラムの最初にこれを行うことができます)。これを使用して、入力値の型情報ポインタに対して実行時のチェックを行います。 proc。

関連する問題