通用序列
Generic Sequences
我有以下片段。第二个变量声明没有编译:
type
Coin = ref object
Pen = ref object
let
yes : seq[ref object] = @[Coin(), Coin(), Coin()] #Compiles
no : seq[ref object] = @[Coin(), Pen(), Coin()] #Does not compile
在 nim 中是否可以使用通用序列,例如 java 的列表?
Nim 序列 是 通用的,但您没有将相同类型的对象放入其中。在 Java 中,所有非原始类型(包括数组)inherit either directly or indirectly from the Object superclass 因此通过 List<Object>
类型,您可以在其中放入任何内容。但在 Nim 中,并非所有东西都必须具有相同的根,在你的情况下,虽然对象看起来相同,但它们被视为不同的类型。所以你需要创建一个 class 层次结构,如 java:
type
BaseRef = ref object of TObject
CoinRef = ref object of BaseRef
PenRef = ref object of BaseRef
let
test1: seq[BaseRef] = @[(BaseRef)CoinRef(), CoinRef(), CoinRef()]
test2: seq[BaseRef] = @[(BaseRef)CoinRef(), PenRef(), CoinRef()]
请注意,@[]
列表构造函数仍然需要在正确的方向上进行操作,将第一个元素转换为基本类型,否则您将得到不等式(seq[BaseRef]
不是 与 seq[CoinRef]
相同,这将由类型推断产生)。
如果出于某种原因需要保留单独的根,作为引用,直接转换它们应该没问题,为此您可以创建辅助过程:
type
AnyRef = ref object
Coin = ref object
Pen = ref object
proc `^`(x: Coin): AnyRef = cast[AnyRef](x)
proc `^`(x: Pen): AnyRef = cast[AnyRef](x)
let
yes : seq[AnyRef] = @[^Coin(), ^Coin(), ^Coin()]
no : seq[AnyRef] = @[^Coin(), ^Pen(), ^Coin()]
或者创建 converter procs 不需要对所有元素进行显式转换,只需要第一个元素,就像继承版本一样:
type
AnyRef = ref object
Coin = ref object
Pen = ref object
converter toAnyRef(x: Coin): AnyRef = cast[AnyRef](x)
converter toAnyRef(x: Pen): AnyRef = cast[AnyRef](x)
let
yes : seq[AnyRef] = @[Coin().toAnyRef, Coin(), Coin()]
no : seq[AnyRef] = @[Coin().toAnyRef, Pen(), Coin()]
我有以下片段。第二个变量声明没有编译:
type
Coin = ref object
Pen = ref object
let
yes : seq[ref object] = @[Coin(), Coin(), Coin()] #Compiles
no : seq[ref object] = @[Coin(), Pen(), Coin()] #Does not compile
在 nim 中是否可以使用通用序列,例如 java 的列表?
Nim 序列 是 通用的,但您没有将相同类型的对象放入其中。在 Java 中,所有非原始类型(包括数组)inherit either directly or indirectly from the Object superclass 因此通过 List<Object>
类型,您可以在其中放入任何内容。但在 Nim 中,并非所有东西都必须具有相同的根,在你的情况下,虽然对象看起来相同,但它们被视为不同的类型。所以你需要创建一个 class 层次结构,如 java:
type
BaseRef = ref object of TObject
CoinRef = ref object of BaseRef
PenRef = ref object of BaseRef
let
test1: seq[BaseRef] = @[(BaseRef)CoinRef(), CoinRef(), CoinRef()]
test2: seq[BaseRef] = @[(BaseRef)CoinRef(), PenRef(), CoinRef()]
请注意,@[]
列表构造函数仍然需要在正确的方向上进行操作,将第一个元素转换为基本类型,否则您将得到不等式(seq[BaseRef]
不是 与 seq[CoinRef]
相同,这将由类型推断产生)。
如果出于某种原因需要保留单独的根,作为引用,直接转换它们应该没问题,为此您可以创建辅助过程:
type
AnyRef = ref object
Coin = ref object
Pen = ref object
proc `^`(x: Coin): AnyRef = cast[AnyRef](x)
proc `^`(x: Pen): AnyRef = cast[AnyRef](x)
let
yes : seq[AnyRef] = @[^Coin(), ^Coin(), ^Coin()]
no : seq[AnyRef] = @[^Coin(), ^Pen(), ^Coin()]
或者创建 converter procs 不需要对所有元素进行显式转换,只需要第一个元素,就像继承版本一样:
type
AnyRef = ref object
Coin = ref object
Pen = ref object
converter toAnyRef(x: Coin): AnyRef = cast[AnyRef](x)
converter toAnyRef(x: Pen): AnyRef = cast[AnyRef](x)
let
yes : seq[AnyRef] = @[Coin().toAnyRef, Coin(), Coin()]
no : seq[AnyRef] = @[Coin().toAnyRef, Pen(), Coin()]