Julia 结构错误“没有匹配迭代的方法”

use*_*001 2 struct julia

在尝试理解 Julia 中的参数结构时,我将以下结构定义为 AbstractSet 的子类型

struct MySet{T} <: AbstractSet{T}
    st::Vector{T}
    MySet(x::Vector{T}) where {T} = new{T}(x)
end
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试创建 MySet 类型的新对象时,出现以下错误

julia> MySet([1,2])

       MethodError: no method matching iterate(::MySet{Int64})
       Closest candidates are:
       iterate(::Union{LinRange, StepRangeLen}) at ~/julia-1.7.1-linux-x86_64/julia- 
       1.7.1/share/julia/base/range.jl:826 
       iterate(::Union{LinRange, StepRangeLen}, ::Integer) at ~/julia-1.7.1-linux- 
       x86_64/julia-1.7.1/share/julia/base/range.jl:826
       iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, 
       Base.ValueIterator{<:Dict}} at ~/julia-1.7.1-linux-x86_64/julia- 
       1.7.1/share/julia/base/dict.jl:695
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我理解为什么我会收到此错误。

Bog*_*ski 5

对象MySet被创建,如下所示:

julia> x = MySet([1,2]);

julia> x.st
2-element Vector{Int64}:
 1
 2
Run Code Online (Sandbox Code Playgroud)

问题是它没有正确显示。原因是AbstractSet有一个show为它们调用的自定义方法,该方法假设您的AbstractSet对象是可迭代的。

AbstractSet您可以通过编写以下内容来了解​​在记录之前应实现的最小方法集:

julia> subtypes(AbstractSet)
5-element Vector{Any}:
 Base.IdSet
 Base.KeySet
 BitSet
 Set
 Test.GenericSet

julia> using Test

julia> methodswith(GenericSet)
[1] isempty(s::GenericSet) in Test
[2] iterate(s::GenericSet, state...) in Test
[3] length(s::GenericSet) in Test
Run Code Online (Sandbox Code Playgroud)

我选择的原因GenericSet是它被记录为:

help?> GenericSet
search: GenericSet GenericString GenericDict GenericOrder GenericArray

The GenericSet can be used to test generic set APIs that program to
the AbstractSet interface, in order to ensure that functions can work
with set types besides the standard Set and BitSet types.
Run Code Online (Sandbox Code Playgroud)

所以GenericSet定义的应该是接口要求的最小值AbstractSet

(上面我向您展示了您可以用来发现需要什么的完整过程,因为GenericSet如果没有前面的步骤,猜测应该检查的内容是不明显的)

  • 另一种看待它的方式(根据[这个黑客新闻评论](https://news.ycombinator.com/item?id=27964054))是这些错误消息是使你的`struct MySet`成为一个正确的` AbstractSet`,遵循其预期的接口。Julia 没有正式的接口,但是当您尝试使用“MySet”作为“AbstractSet”时,这些错误消息可以告诉您缺少预期接口的哪些部分。 (2认同)
  • 然而,需要明确的是,我更喜欢 Julia 拥有正确记录的接口(不仅仅是 AbstractArrays](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array) ),也许我们将来会得到这些。上面只是一种实用的、丑陋的方式,利用当前的行为来解决问题。 (2认同)