Вот итератор, который я не хочу копировать:
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]
Это работает на:
for i in testI(@[1,2,3]):
echo 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]
Обратите внимание, я просто добавил var к параметру и вернулся. Но это больше не работает для случая без var выше.
Насколько я могу судить, эта проблема эквивалентна выполнению следующей работы:
proc foo[A, B](x: A, fn: B) =
fn(x)
var x = 1
foo(x, proc(x: var int) = x += 1)
foo(1, proc(x: int) = echo x)
assert x != 1
Почему-то это даже не работает:
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
В языке программирования D есть такие параметры, как «автоссылка», которые выбирают либо ссылочные параметры, либо параметры значения в зависимости от того, являются ли они lvalue или нет.
Почему это такая трудная проблема? Я не хочу копировать и вставлять функцию каждый раз, когда я создаю итератор.