3

我有以下片段。第二个变量声明虽然没有编译:

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 的 list ?

4

1 回答 1

5

Nim 序列通用的,但您不会在其中放入相同类型的对象。在 Java 中,所有非原始类型(包括数组)都直接或间接继承自 Object 超类,因此通过拥有List<Object>类型,您可以在其中放入任何内容。但是在 Nim 中,并非所有内容都必须具有相同的根,在您的情况下,虽然对象看起来相同,但它们被视为不同的类型。所以你需要创建一个像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()]

请注意,@[]列表构造函数仍需要以正确的方向推动将第一个元素转换为基本类型,否则您将得到一个不等式( aseq[BaseRef]与a 不同seq[CoinRef]这将由类型推断产生)。

如果您出于某种原因需要保留单独的根,作为 refs 应该可以直接转换它们,您可以为此创建辅助过程:

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()]

或者可能创建不需要对所有元素进行显式转换的转换器过程,只需要第一个元素,就像继承版本一样

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()]
于 2015-04-22T20:42:07.827 回答