Działa to z powodu jednej z najbardziej podstawowych cech Julii: wielokrotnej wysyłki. W Julii funkcje mogą mieć wiele metod, które mają zastosowanie do różnych kombinacji typów argumentów, a kiedy wywołujesz funkcję, Julia wywołuje najbardziej specyficzną metodę, która pasuje do wszystkich argumentów, które wywołałeś. Wywołanie //
w opublikowanej definicji metody definiuje wartość rational-integer //
pod względem liczby całkowitej integer //
- więc nie jest rekurencyjne, ponieważ metoda nie wywołuje samej siebie, wywołuje inną metodę, która jest częścią tego samego " funkcja ogólna ".
Aby zrozumieć, jak działa wielokrotna wysyłka w tym przypadku, rozważmy ocenę wyrażenia (3//4)//6
. Użyjemy makra @which
, aby zobaczyć, która metoda wywołuje każde wywołanie funkcji.
julia> @which (3//4)//6
//(x::Rational{T<:Integer}, y::Integer) at rational.jl:25
Od 3//4
jest Rational{Int} <: Rational
i 6
jest Int <: Integer
i zastosowania żadne inne bardziej specyficzne metody, metoda ta nazywa się:
//(x::Rational, y::Integer) = x.num // (x.den*y)
The current version metody jest rzeczywiście nieco bardziej skomplikowany niż to, co wysłałeś, ponieważ został zmodyfikowany, aby sprawdzić przepełnienie - ale zasadniczo jest taki sam i łatwiej jest zrozumieć starszą, prostszą wersję, więc wykorzystam to. Załóżmy przypisać x
i y
do argumentów i zobaczyć, jaka metoda nazywa definicja:
julia> x, y = (3//4), 6
(3//4,6)
julia> x.num
3
julia> x.den*y
24
julia> x.num // (x.den*y)
1//8
julia> @which x.num // (x.den*y)
//(n::Integer, d::Integer) at rational.jl:22
Jak widać, to wyrażenie nie wywołuje ten sam sposób, to nazywa different method:
//(n::Integer, d::Integer) = Rational(n,d)
Ta metoda po prostu wywołuje konstruktor Rational
, który ustawia stosunek n
i d
na najniższe terminy i tworzy obiekt liczbowy Rational
.
Jest dość powszechne, aby zdefiniować jedną metodę funkcji w odniesieniu do innej metody tej samej funkcji, w Julia. Na przykład działają domyślne argumenty.Rozważmy taką definicję:
julia> f(x, y=1) = 2x^y
f (generic function with 2 methods)
julia> methods(f)
# 2 methods for generic function "f":
f(x) at none:1
f(x, y) at none:1
julia> f(1)
2
julia> f(2)
4
julia> f(2,2)
8
Składnia argumentem domyślnym po prostu generuje drugi sposób tylko onee argumentu, który wzywa formę dwóch argument z wartości domyślnej. Więc f(x, y=1) = 2x^y
jest dokładnie równoważne określenie dwóch metod, gdzie metoda jednoskładnikowa prostu wywołuje metodę binarnego, dostarczając wartość domyślną dla drugiego argumentu:
julia> f(x, y) = 2x^y
f (generic function with 1 method)
julia> f(x) = f(x, 1)
f (generic function with 2 methods)
To był bardzo klarowny. Dziękuję Ci. – dopatraman