【问题标题】:Julia multiple dispatch not matching subtypesJulia 多次调度与子类型不匹配
【发布时间】:2020-03-20 08:12:30
【问题描述】:

有人能帮我理解为什么这个 julia 函数定义与我在下面看到的使用它的尝试不匹配吗?

我幼稚的假设是传递给函数的Array{ASCIIString,1} 应该与Array{AbstractString,1} 的函数定义匹配,依此类推。

julia> function test(a::Array{AbstractString,1}, b::AbstractString, c::Any) end
test (generic function with 1 method)

julia> test([""],"","")
ERROR: MethodError: `test` has no method matching test(::Array{ASCIIString,1}, ::ASCIIString, ::ASCIIString)
Closest candidates are:
  test(::Array{AbstractString,1}, ::AbstractString, ::Any)

julia>

【问题讨论】:

  • 原因是 Julia 类型是 invariant 这意味着 issubtype(Array{ASCIIString,1},Array{AbstractString,1}) 是假的。更多信息请查看docs.julialang.org/en/release-0.4/manual/types/…
  • 这是this question 中问题的一个简单示例。然而,这个问题的呈现方式有很大的不同,我投票认为我们保持开放。为了快速参考,您需要的语法是function test{T<:AbstractString}(a::Array{T}, b::T, c::Any),但如果您希望a 的元素类型与b 的类型不同,您可能需要第二个类型参数...
  • 糟糕,忽略我之前评论中关于“第二类型参数”的废话。如果你想让a 的元素类型和b 的类型不同,那么function test{T<:AbstractString}(a::Array{T}, b::AbstractString, c::Any) 就足够了。关键是ASCIIString <: AbstractStringtrue,而Array{ASCIIString, 1} <: Array{AbstractString, 1}false

标签: julia


【解决方案1】:

我认为将我上面的两个 cmets 变成一个答案是值得的。

正如@DanGetz 所指出的,这里的重要短语是invariant。在这种特殊情况下,此原则意味着ASCIIString <: AbstractString 的计算结果为true,但Array{ASCIIString, 1} <: Array{AbstractString, 1} 的计算结果为false。因此,要使问题中定义的函数起作用,您需要传入一个数组aeltype(a) 评估为AbstractString。将aeltype(a) 评估为ASCIIString 一起传递是行不通的,因为这不是Array{AbstractString, 1} 的子类型。

要解决您的问题,您需要类型参数。如果您只想为b 的类型与eltype(a) 匹配的情况定义函数,那么您可以使用:

function test{T<:AbstractString}(a::Array{T}, b::T, c::Any)

如果您想允许b 的类型不同于eltype(a),但强制bAbstractString 的子类型,您可以使用:

function test{T<:AbstractString}(a::Array{T}, b::AbstractString, c::Any)

【讨论】:

  • 完美解释,谢谢!对于关注此问题的其他人,我必须查找一些内容:eltype(...) 返回集合的类型,例如:eltype(Array{ASCIIString, 1}) # Returns: ASCIIString。此外,我发现这篇文章相关且有用:stackoverflow.com/questions/20991220/…
  • @DavidParks 很高兴为您提供帮助!
【解决方案2】:

自从 Colin 回答后,Julia 的语法发生了变化。从 Julia 版本 1 开始,它看起来像这样:

function test(a::Array{T}, b::T, c::Any) where {T<:AbstractString}

见:https://docs.julialang.org/en/v1/manual/methods/#Methods-1

【讨论】:

    猜你喜欢
    • 2020-11-27
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多