2

次のような単純なクラス階層を作成する場合:

type
  fooObj = ref object {.inheritable.}
  barObj = ref object of fooObj
  bazObj = ref object of fooObj
    x: string

var troz: fooObj

let bar = barObj()
let baz = bazObj(x: "yes")

echo bar[]
# ()
echo baz[]
# (x: yes)
troz = bar 
echo troz[]
# ()
troz = baz 
echo troz[]
# ()
echo bazObj(troz).x
#yes

x型のメンバー変数にアクセスすると、期待される出力 (行に表示) が得られますbazObj

ジェネリックを使用して同様の階層を作成すると、コードは正常にコンパイルされますが、ObjectConversionError例外がスローされます。私の構文は間違っていますか?それとも、Nim ではサポートされていないジェネリックを使用したこのタイプのオブジェクト変換ですか?

type
  fooObj[T] = ref object {.inheritable.}
  barObj[T] = ref object of fooObj[T]
  bazObj[T] = ref object of fooObj[T]
    x: T

var troz: fooObj[system.string]

let bar = barObj[system.string]()
let baz = bazObj[system.string](x: "yes")

echo bar[]
# ()
echo baz[]
# (x: yes)
troz = bar 
echo troz[]
#()
troz = baz 
echo troz[]
#()
echo bazObj[system.string](troz).x
#Traceback (most recent call last)
#foo.nim(22)           foo
#Error: unhandled exception: invalid object conversion [ObjectConversionError]

22 行目を に置き換えるとecho bazObj(troz).x、コンパイル時に次のようになります。

foo.nim(22, 13) Error: type mismatch: got (fooObj[system.string]) but expected 'bazObj'
4

1 に答える 1

2

わかりましたので、アプローチを少し変更し、代わりにオブジェクト バリアントを使用しました。上記で試したことがうまくいくかどうかはまだわかりません。

私が達成しようとしていたのは、Scala や他の言語で利用できる基本Optionまたは型でした。Maybe

これは私が最終的に実装したものであり、正確には「実際の」Optionタイプではありませんが、これまでにやりたいことに対して機能します。

type
  OptionKind = enum
    okNone,
    okSome
  Option*[T] = ref OptionObj[T]
  OptionObj[T] = object
    isDefined: bool
    case kind: OptionKind
    of okNone: discard
    of okSome: x: T

proc None*[A](): Option[A] =
  Option[A](kind: okNone)

proc Some*[A](x: A): Option[A] =
  Option[A](kind: okSome, x: x, isDefined: true)

proc isSome*[A](x: Option[A]): bool =
  x.isDefined

proc isNone*[A](x: Option[A]): bool =
  not x.isDefined

proc get*[A: Option, B](this: A): B =
  if this.isNone:
    raise newException(NoSuchElement, "Failed to get from None")
  this.x

proc getOrElse*[A: Option, B](this: A, default: B): B =
  if this.isSome:
    this.x
  else:
    default

proc isEmpty*[A: Option](this: A): bool =
  not this.isDefined

type NoSuchElement* = object of Exception
于 2015-05-13T09:21:04.127 に答える