澄清 julia 中的函数签名和调度行为

Clarification on function signature and dispatching behaviour in julia

我在 Julia (1.2) REPL 中尝试了一些东西,但我一直在想一些我不了解调度的东西。


我第一次尝试了这个东西,它按我预期的方式工作:

f(a::T) where {T <: Int} = "Test"


然后,我尝试了这个方法,但我不明白为什么在某些情况下调用它会起作用:

f(a::T, b::U) where {T, U <: T} = "Another Test"

我认为(因为 T 变成了 Int 而 U 变成了 String)String <: Int == false ???


我想我在这里遗漏了一些非常简单的东西,但我找不到... 所以这是我的问题,为什么 f(3, "Hello") 有效???


此外,我尝试了这段代码(我试图重新创建第二个方法签名),但它如我所料正确地失败了:

Test = Tuple{T, U} where {T, U <: T}

Test{Int, String}(正如我预期的那样失败 "TypeError: in Type, in U, expected U<:Int64, got Type{String}")

这里发生的事情是 T 可以是数据类型,而 U 可以是字符串的任何超类型。这样条件就满足了。 string 不是 int 的子类型让你感到困惑的事情是一个红色鲱鱼,因为没有具体类型是任何其他类型的子类型。

好的,多亏了laborg,我现在似乎明白发生了什么事了。如果我们采用这种方法:

f(a::T, b::U) where {T, U <: T} = "Another Test"

  • 'T' 是 "UnionAll" 又名 "Iterated Union" 所有可能类型的 'a'。
  • 'U' 是 "UnionAll" 又名 "Iterated Union" 'b' 的所有可能类型,它们是 'T'[=12 的子类型=]

  • 我误解的事实是如果(示例)a::Int,那么 T 可以采用 typeof(a) 的父抽象类型。由于 Int <: Any,那么 T = Any 是调度的有效解决方案。

  • U = Any 相同,因为 String <: Any。

所以我们现在有 U <: T 解析为 Any <: Any == true,然后调用该方法!

我希望我明白了:)