【发布时间】:2019-01-22 14:58:40
【问题描述】:
我正在查看来自http://lostella.github.io/blog/2018/07/25/iterative-methods-done-right 的迭代器示例并有一个问题。以下工作并产生高达 13 的斐波那契数:
iterate(f::FibonacciIterable) = f.s0, (f.s0, f.s1)
iterate(f::FibonacciIterable, state) = state[2], (state[2], state[1] + state[2])
for f in FibonacciIterable(0, 1)
print("$f ")
if f > 10 println(); break end
end
我正在尝试将两个 iterate 函数替换为一个,并配置了默认值:
iterate(f::FibonacciIterable, state = (f.s0, (f.s0, f.s1)) ) = (state[2], state[1] + state[2])
运行此代码会产生:
ERROR: LoadError: MethodError: no method matching +(::Int64, ::Tuple{Int64,Int64})
Closest candidates are:
+(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:502
+(::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}, !Matched::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:53
+(::Union{Int16, Int32, Int64, Int8}, !Matched::BigInt) at gmp.jl:456
注意:使用 Julia 1.0
在此评论 Bogumił Kamiński 的关于格式化和额外空间的回答
谢谢 Bogumił - 但我仍然很难建立一个关于其工作原理的心智模型。首先还有以下 产生预期的输出:
iterate(iter::FibonacciIterable, state=(iter.s1, iter.s0)) = state[2], (state[2], sum(state))
文档说:
iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}}
Advance the iterator to obtain the next element. If no elements remain, nothing should be returned.
Otherwise, a 2-tuple of the next element and the new iteration state should be returned.
按照我的阅读方式,第一次调用这个版本的iterate会返回iter.s1并设置下一个状态
成为iter.s0。所以第一次调用的输出应该是1,而下一次调用iterate 应该会失败
因为没有 state[2] 这样的东西。显然这不是正在发生的事情,因为第一个值是 0 并且计算继续进行而没有错误。你能指出我的逻辑哪里出错了吗?
评论 2
正确 - 这有帮助:
julia> iterate(FibonacciIterable(BigInt(2), BigInt(3)))
(2, (2, 3))
我假设名为state 的参数和iterate 的返回类型(我认为是下一个状态)属于同一类型。
正如您指出的那样,state 参数的类型不是Tuple{I,I},但返回值的类型是Tuple{I, Tuple{I,I}}(实际上是Union{Nothing, Tuple{I, Tuple{I,I}}},但没关系)其中“内部”元组是状态。
【问题讨论】:
标签: julia