Nim 支持自动投射吗?
Does Nim support autocasting?
我试图对序列中特定类型的对象调用函数,但编译器报错。
如何解决?我需要从 TextDoc
对象中获取 text
属性。
type
DocItem = object of RootObj
tags: seq[string]
TextDoc = object of DocItem
text: string
TodoDoc = object of DocItem
todo: string
var docs: seq[ref DocItem]
proc to_ref[T](o: T): ref T =
result.new
result[] = o
docs.add TextDoc(text: "some doc").to_ref
docs.add TodoDoc(todo: "some todo").to_ref
for d in docs:
if d of TextDoc:
echo d.text
错误
Error: undeclared field: 'text'
of
条件语句不会神奇地转换块其余部分的类型,我会转换类型,或者编写一个额外的辅助过程来完成它:
proc toTextDoc(thing: ref DocItem): ref TextDoc = cast[ref TextDoc](thing)
proc toTodoDoc(thing: ref DocItem): ref TodoDoc = cast[ref TodoDoc](thing)
for d in docs:
if d of TextDoc:
echo d.toTextDoc.text
elif d of TodoDoc:
echo d.toTodoDoc.todo
else:
echo "Not a ref?"
要对已接受的答案发表评论,cast
是一种不安全的操作,除非您有特定理由使用它,否则应避免使用它。您可以改用类型转换,如下所示:
for d in docs:
if d of ref TextDoc:
echo TextDoc(d[]).text
如果你使 TextDoc
和 TodoDoc
ref object of DocItem
那么你可以摆脱你的 to_ref
过程,并像这样编写循环:
for d in docs:
if d of TextDoc:
echo TextDoc(d).text
或者您可以使用对象变体,这可能是最惯用的方法:
type
DocType = enum dtText, dtTodo
DocItem = ref object
tags: seq[string]
case kind: DocType
of dtText: text: string
of dtTodo: todo: string
var docs = @[DocItem(kind: dtText, text: "some doc"),
DocItem(kind: dtTodo, todo: "some todo")]
for d in docs:
if d.kind == dtText:
echo d.text
我试图对序列中特定类型的对象调用函数,但编译器报错。
如何解决?我需要从 TextDoc
对象中获取 text
属性。
type
DocItem = object of RootObj
tags: seq[string]
TextDoc = object of DocItem
text: string
TodoDoc = object of DocItem
todo: string
var docs: seq[ref DocItem]
proc to_ref[T](o: T): ref T =
result.new
result[] = o
docs.add TextDoc(text: "some doc").to_ref
docs.add TodoDoc(todo: "some todo").to_ref
for d in docs:
if d of TextDoc:
echo d.text
错误
Error: undeclared field: 'text'
of
条件语句不会神奇地转换块其余部分的类型,我会转换类型,或者编写一个额外的辅助过程来完成它:
proc toTextDoc(thing: ref DocItem): ref TextDoc = cast[ref TextDoc](thing)
proc toTodoDoc(thing: ref DocItem): ref TodoDoc = cast[ref TodoDoc](thing)
for d in docs:
if d of TextDoc:
echo d.toTextDoc.text
elif d of TodoDoc:
echo d.toTodoDoc.todo
else:
echo "Not a ref?"
要对已接受的答案发表评论,cast
是一种不安全的操作,除非您有特定理由使用它,否则应避免使用它。您可以改用类型转换,如下所示:
for d in docs:
if d of ref TextDoc:
echo TextDoc(d[]).text
如果你使 TextDoc
和 TodoDoc
ref object of DocItem
那么你可以摆脱你的 to_ref
过程,并像这样编写循环:
for d in docs:
if d of TextDoc:
echo TextDoc(d).text
或者您可以使用对象变体,这可能是最惯用的方法:
type
DocType = enum dtText, dtTodo
DocItem = ref object
tags: seq[string]
case kind: DocType
of dtText: text: string
of dtTodo: todo: string
var docs = @[DocItem(kind: dtText, text: "some doc"),
DocItem(kind: dtTodo, todo: "some todo")]
for d in docs:
if d.kind == dtText:
echo d.text