4

Julia 0.5 の変更ログによると、

各関数とクロージャーには独自の型があります。

これは、より詳細な情報を高次関数に提供できるようになったことを意味しますfoo(bar :: Function{Float64}) = ...か?barFunction

もしそうなら、そうする正しい方法は何ですか?そうでない場合、コンパイラが生成されたコードをより適切に最適化できる以外に、この変更の実際のインポートは何ですか? ティア。

4

1 に答える 1

5

いいえ、そうではありません。私はあなたが何を得ているかを見て、それが好きですが、それは不可能です. (確かに現在ではありません。おそらく今後もありません。いつか特性を使用するかもしれません。)

例を見てみましょうfoo:bar

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)

型階層とは何fooですか?

julia> typeof(foo)
#foo

julia> supertype(typeof(foo))
Function

julia> supertype(supertype(typeof(foo)))
Any

fooしたがって、関数の型#fooは のサブタイプである であることがわかりますFunction。これは生成された名前であることを意味することに注意してください#。コードを書くだけではハッシュを名前に入れることはできませんが、ジュリアコンパイラー(用語を大まかに使用)はできます。

そのスーパースーパータイプが機能だけでなく、より具体的でないのはなぜですか? それはどうなりますか?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

dothingしたがって、引数としてa のみを取るように を制限すること#fooに成功しました。を与えるとエラーがスローされることを確認してください#barfoo関数は type の唯一のものであるため、これはあまり役に立ちません#foo

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

dootherthing#fooまたはを受け入れます#bar。どちらの機能も動作します。

これは、ホワイトリストとして、用途が限られています。

于 2016-09-24T01:38:23.100 に答える