在 Crystal 中实现惰性枚举器
Implementing Lazy Enumerator in Crystal
在 Ruby 中构建自定义惰性枚举器,可以像这样利用 Enumerator
:
enum = Enumerator.new do |e|
e << value = ".a"
loop { e << value = value.next }
end
enum.next # => ".a"
enum.next # => ".b"
enum.next # => ".c"
enum.rewind
enum.next # => ".a"
Crystal模仿这种东西的惯用方式是什么?
有点啰嗦...看看Iterator<T>
class DotChar
include Iterator(String)
@current : String = ""
def initialize
@start = ".a"
rewind
end
def next
@current.tap { @current = @current.succ }
end
def rewind
@current = @start
end
end
e = DotChar.new
p e.next # => ".a"
p e.next # => ".b"
p e.next # => ".c"
e.rewind
p e.next # => ".a"
(不能使用 enum
作为标识符,因为它是 Crystal 中的关键字。)
如果你牺牲倒带,你可以做得更简单:
s = ".a"
e = Iterator.of { s.tap { s = s.succ } }
将来可能会有一种方法可以完全按照 Ruby 进行操作,但这是一项正在进行的工作(我希望还没有被放弃,它似乎在半年前就停滞了).有关详细信息,请参阅 this issue and this pull request。
在 Ruby 中构建自定义惰性枚举器,可以像这样利用 Enumerator
:
enum = Enumerator.new do |e|
e << value = ".a"
loop { e << value = value.next }
end
enum.next # => ".a"
enum.next # => ".b"
enum.next # => ".c"
enum.rewind
enum.next # => ".a"
Crystal模仿这种东西的惯用方式是什么?
有点啰嗦...看看Iterator<T>
class DotChar
include Iterator(String)
@current : String = ""
def initialize
@start = ".a"
rewind
end
def next
@current.tap { @current = @current.succ }
end
def rewind
@current = @start
end
end
e = DotChar.new
p e.next # => ".a"
p e.next # => ".b"
p e.next # => ".c"
e.rewind
p e.next # => ".a"
(不能使用 enum
作为标识符,因为它是 Crystal 中的关键字。)
如果你牺牲倒带,你可以做得更简单:
s = ".a"
e = Iterator.of { s.tap { s = s.succ } }
将来可能会有一种方法可以完全按照 Ruby 进行操作,但这是一项正在进行的工作(我希望还没有被放弃,它似乎在半年前就停滞了).有关详细信息,请参阅 this issue and this pull request。