Generics 在Nim中使用泛型转换类型时出现ObjectConversionError
当我设计一个简单的类层次结构时,例如:Generics 在Nim中使用泛型转换类型时出现ObjectConversionError,generics,nim-lang,Generics,Nim Lang,当我设计一个简单的类层次结构时,例如: 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
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
当访问bazObj
类型的x
成员变量时,我得到了预期的输出(如第行所示)
当我创建一个类似的层次结构但使用泛型时,代码可以很好地编译,但会抛出一个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'
好的,所以我稍微改变了我的方法,改为使用对象变量。我仍然不确定我在上面尝试的是否有效 我试图实现的是一个基本的
选项
或可能
类型,可以在Scala和其他语言中使用
这就是我最终实现的,它不完全是一个“真正的”选项
类型,但它适用于到目前为止我想要做的事情
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
对我来说这看起来像个虫子。第一个应该抛出一个异常,或者第二个不应该抛出一个异常,我不确定是哪一个,因为您正在尝试转换一个空指针,而它实际上不是您想要转换为的子类型。这对您来说应该很有趣。在链接的IRC讨论中,还解释了为什么对象变量不如简单的布尔+值。我的第一个实现与您的非常相似:)。请注意,
isDefined
是冗余的,将其设为ref
类型可能不是一个好主意。嘿,看起来我来得正是时候。期待该请求被合并。@bluenote10谢谢,查看了您的代码,非常有用@洛库林:哦,我不是故意要为此得到赞扬的。这都是无稽之谈。我只看到了一些可能妨碍函数式编程的问题,并提出了一些小的修改。