问题描述
据我所知,下面的代码产生ObjectAssignmentError
,这是因为序列定义为seq[Doc]
而不是seq[TextDoc]
。
但是难道这样的错误不应该在编译时由编译器捕获并且不会泄漏到运行时吗?
type
Doc = object of RootObj
TextDoc* = object of Doc
title*: string
text*: string
TodoDoc* = object of Doc
todo*: string
var all_docs*: seq[Doc] = @[]
all_docs.add TextDoc(title: "",text: "")
解决方法
之所以没有在编译时捕获它,是因为通常可以将TextDoc
添加到Doc
的数组中,只要已明智地声明它们即可,即异构数组必须是ref objects
或Variants(否则它们不能全部放在同一个空格中)
换句话说:继承意味着任何接受Doc
的过程也将接受TextDoc
,包括该过程
proc add(s:var seq[Doc],d:Doc)
Nim支持值语义,这对于高速缓存友好性很重要,但这种自由可能会使以前使用的语义感到不安。 Java,所有内容均通过引用传递。
具有参考语义,以上代码运行无错误:
type
Doc = ref object of RootObj
TextDoc* = ref object of Doc
title*: string
text*: string
TodoDoc* = ref object of Doc
todo*: string
var all_docs*: seq[Doc] = @[]
all_docs.add TextDoc(title: "",text: "blah")
assert TextDoc(all_docs[0]).text == "blah"