Parameters 迭代器的泛型可变和不可变参数

Parameters 迭代器的泛型可变和不可变参数,parameters,nim-lang,mutability,Parameters,Nim Lang,Mutability,这是我不想复制的迭代器: iterator testI[T](arr: seq[T]): T = # I don't want to copy-paste this body # In a real world example it might be much bigger for i in 0 ..< arr.len: yield arr[i] 但不是关于: var lst = @[1,2,3] for i in testI(lst): i += 1 ech

这是我不想复制的迭代器:

iterator testI[T](arr: seq[T]): T =
  # I don't want to copy-paste this body
  # In a real world example it might be much bigger
  for i in 0 ..< arr.len:
    yield arr[i]
但不是关于:

var lst = @[1,2,3]
for i in testI(lst):
  i += 1
  echo i
我可以将迭代器定义替换为:

iterator testI[T](arr: var seq[T]): var T =
  # I don't want to copy-paste this body
  # In a real world example it might be much bigger
  for i in 0 ..< arr.len:
    yield arr[i]
出于某种原因,这甚至不起作用:

iterator testI[A, B](arr: A): B =
  # I don't want to copy-paste this body
  # In a real world example it might be much bigger
  for i in 0 ..< arr.len:
    yield arr[i]
var lst = @[1,2,3]
for i in testI[var seq[int], var int](lst):
  i += 1
迭代器testI[A,B](arr:A):B= #我不想复制粘贴这个身体 #在现实世界的例子中,它可能要大得多 对于0中的i.. 在D编程语言中,有这样的“auto-ref”参数,根据它们是否为左值选择为参考参数或值参数


为什么这是一个如此困难的问题?我不想每次创建迭代器时都要复制粘贴函数。

通常在Nim中,您会发现两个迭代器:
items
mitems
,一个用于获取项而不修改它们,另一个用于允许修改。在尝试实施一些疯狂的事情之前,我会努力使用这些程序

但有时您必须实现它,因此,每当您发现自己在Nim中遇到可以用Ctrl-C Ctrl-V解决的“代码重复”问题时,您应该考虑使用“模板”。例如

这是在OpenArray的
mitems
中定义的代码(已通过
system
导入到您的代码中),因此上述代码可以重写为:

var lst = @[1, 2, 3]
for i in mitems(lst):
  i += 1

echo lst
# @[2, 3, 4]
iterator testI[A, B](arr: A): B =
  # I don't want to copy-paste this body
  # In a real world example it might be much bigger
  for i in 0 ..< arr.len:
    yield arr[i]
var lst = @[1,2,3]
for i in testI[var seq[int], var int](lst):
  i += 1
template myCycle =
  ## Long and tedious code here.
  for i in 0 ..< arr.len:
    yield arr[i]

iterator testI[T](arr: seq[T]): T =
  echo "Non-var type"
  myCycle

iterator testI[T](arr: var seq[T]): var T =
  echo "Var type"
  myCycle

var lst1 = @[1,2,3]
for i in testI(lst1):
  echo i

let lst2 = @[1,2,3]
for i in testI(lst2):
  echo i
iterator testI[T](a: var openArray[T]): var T {.inline.} =
  var i = 0
  while i < len(a):
    yield a[i]
    inc(i)

var lst = @[1, 2, 3]
for i in testI(lst):
  i += 1

echo lst
# @[2, 3, 4]
var lst = @[1, 2, 3]
for i in mitems(lst):
  i += 1

echo lst
# @[2, 3, 4]