为什么在Nim的编译时未捕获到分配错误?

问题描述

据我所知,下面的代码产生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"