generics - 通用序列

标签 generics sequence nim-lang

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

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> type 你可以在里面放任何东西。但在 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()]

请注意 @[]列表构造函数仍然需要在正确的方向上将第一个元素转换为基本类型,否则你会得到一个不平等(seq[BaseRef]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()]

或者创建 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()]

关于generics - 通用序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29801308/

相关文章:

java - 什么是 PECS(生产者扩展消费者 super )?

generics - 如何将特征对象传递给向量,该向量在向量的向量中也具有统一的类型?

Python2 : List splitting syntax - tail of a list

nim-lang - 如何在 Nimrod 中使用函数指针?

file - 在 Nim 中捆绑静态资源的最佳方法是什么?

java - 通用类型转换/实例检查/排除类型参数

C# 通用接口(interface)

sql - Oracle表在同一个表中插入时自动递增

algorithm - 重新创建序列

arrays - 尼姆 : find the index of an item in an array or sequence