Collections 集合和数组之间是否存在集合超类型?如果不是,函数如何在集合和数组上都是多态的(用于迭代)?

Collections 集合和数组之间是否存在集合超类型?如果不是,函数如何在集合和数组上都是多态的(用于迭代)?,collections,julia,Collections,Julia,Julia中是否存在一个集合类型,集合和数组都是从中派生的 我有两个: julia> supertype(Array) DenseArray{T,N} where N where T julia> supertype(DenseArray) AbstractArray{T,N} where N where T julia> supertype(AbstractArray) Any 以及: 我试图实现的是编写一个函数,该函数可以将Array或Set作为参数,因为只要我可以迭

Julia中是否存在一个
集合
类型,
集合
数组
都是从中派生的

我有两个:

julia> supertype(Array)
DenseArray{T,N} where N where T

julia> supertype(DenseArray)
AbstractArray{T,N} where N where T

julia> supertype(AbstractArray)
Any
以及:

我试图实现的是编写一个函数,该函数可以将
Array
Set
作为参数,因为只要我可以迭代它,集合的类型就无关紧要

function(Collection{SomeOtherType} myCollection)
    for elem in myCollection
        doSomeStuff(elem)
    end
end

不,没有
集合
类型,也没有
Iterable
类型

从理论上讲,你的要求可以通过特质来实现,你可以在其他地方读到。然而,我认为不应该在这里使用traits,而应该简单地避免将参数的类型限制为函数。就是说,不做,

foo(x::Container) = bar(x)
,做


不会有性能差异。

如果要限制参数类型,可以创建:

这对集合和数组都有效 但不包括数字
能够限制类型不是性能问题,而是尽快生成错误的问题。因为我为我的自定义类型重新定义了公共运算符,所以我的函数可以在标准数字或字符串上无误地执行。但这是不应该的,如果我错误地使用了错误的类型,它可能会在以后的程序中造成严重破坏。这就是动态语言的诅咒。你只是让它在那里失败。Julia中的iterable被精确定义为“基于
Base.iterate
工作的东西”。我认为您的代码执行“在标准数字或字符串上没有错误”正是泛型编程所能实现的,也是代码组合和重用在Julia中工作良好的原因。转变视角,接受或接受那些最初看起来像是一种不完美的东西,这是朱莉娅哲学的一部分。有一天,有人(包括你自己)可能会尝试将代码用于你最初没有预料到的事情,并发现它“正常工作”。太棒了!您甚至可以通过编写:
Iterable{N}=Union{AbstractArray{N},AbstractSet{N}
来进一步推动,它可以按预期的方式工作。示例:
julia>f(aarg::Iterable{Float64})=5f(带有1个方法的泛型函数)julia>f([1.0,2.0,3.0])5julia>f([1,2,3])错误:MethodError错误:没有方法匹配f(::数组{Int64,1})最近的候选是:f(::Union{AbstractSet{Float64},AbstractArray{Float64,N}),其中N})
关于给出早期错误消息,我建议把第一点查进去。这可能不是您的用例,但看到要避免的事情可能会很有用。
foo(x::Container) = bar(x)
foo(x) = bar(x)
julia> ty = Union{AbstractArray,AbstractSet}
Union{AbstractSet, AbstractArray}

julia> f(aarg :: ty) = 5
f (generic function with 1 method)
julia> f(1:10)
5
julia> f(rand(10))
5
julia> f(Set([1,2,5]))
5
julia> f(5)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f(::Union{AbstractSet, AbstractArray}) at REPL[2]:1