调度Julia v0.5 +中的函数

Are*_*lis 4 types function multiple-dispatch julia

根据Julia 0.5的更新日志,

每个函数和闭包现在都有自己的类型.

这是否意味着现在可以向更高阶的函数提供更详细的信息,例如foo(bar :: Function{Float64}) = ...,与0.5之前相比,其中的类型bar不能更具体Function

如果是这样,这样做的正确方法是什么?如果没有,除了编译器能够更好地优化生成的代码之外,这个变化的实际导入是什么?TIA.

Lyn*_*ite 5

不是真的没有.我看到你得到了什么,我喜欢它,但这是不可能的.(当然不是,目前也可能不会.也许是oneday使用特征.)

让我们看一个例子:foobar

julia> foo(x::String) = println(x)
foo (generic function with 1 method)

julia> foo(x::Int64) = println(x+1)
foo (generic function with 2 methods)

julia> bar(x...) = println(x)
bar (generic function with 1 method)
Run Code Online (Sandbox Code Playgroud)

什么是类型层次结构foo

julia> typeof(foo)
#foo

julia> supertype(typeof(foo))
Function

julia> supertype(supertype(typeof(foo)))
Any
Run Code Online (Sandbox Code Playgroud)

所以我们看到它们的foo函数类型#foo是一个子类型Function.注意,这#意味着这是一个生成的名称,在编写代码时不能将哈希值放在名称中,但是julia编译器(使用松散的术语)可以.

为什么它的超级超类型不仅仅比功能更具体? 会是什么?Function{Int64}还是Function{String}julia中的函数,没有类型签名,方法呢. 一个函数只是多个调度的名称,一个方法实际上是调度到的.粗略地说,函数名称表示我应该查看哪个表,并且参数的类型(即它的类型签名)是在该表中查找的关键.方法本身就是使用该键返回的内容.

让我们继续我们的示例,看看我们能做些什么:

julia> dothing(f::typeof(foo)) = f(rand([randstring(), rand(Int64)]))
dothing (generic function with 1 method)

julia> dothing(foo)
3139374763834167054

julia> dothing(foo)
Ed2kNGrd


julia> dothing(bar)
ERROR: MethodError: no method matching dothing(::#bar)
Closest candidates are:
  dothing(::#foo) at REPL[11]:1
Run Code Online (Sandbox Code Playgroud)

所以我们成功地限制了dothing,只考虑了#foo它的争论.当你给它时,看到它会抛出一个错误#bar.这不是很有用,因为foo函数是唯一的类型#foo.

我们可以使用a Union:

julia> dootherthing(f::Union{typeof(foo),typeof(bar)}) = f(rand([randstring(), rand(Int64)]))
dootherthing (generic function with 1 method)

julia> dootherthing(foo)
9107791406050657562

julia> dootherthing(foo)
SmB2Xmw8

julia> dootherthing(bar)
("1IpZIMnx",)

julia> dootherthing(bar)
(-6356894350805213697,)


julia> dootherthing(str)
ERROR: UndefVarError: str not defined

julia> dootherthing(string)
ERROR: MethodError: no method matching dootherthing(::Base.#string)
Closest candidates are:
  dootherthing(::Union{#bar,#foo}) at REPL[19]:1
Run Code Online (Sandbox Code Playgroud)

dootherthing接受a #foo或a #bar.两种功能都有效.

作为白名单,这有限的应用程序.