Recursion 理解Julia中的无基递归

Recursion 理解Julia中的无基递归,recursion,julia,recursive-datastructures,Recursion,Julia,Recursive Datastructures,此代码段来自Julia中的实现: # Rational.jl # ... Rational{T<:Integer}(n::T, d::T) = Rational{T}(n,d) Rational(n::Integer, d::Integer) = Rational(promote(n,d)...) Rational(n::Integer) = Rational(n,one(n)) //(x::Rational, y::Integer) = x.num // (x.den*y) <-

此代码段来自Julia中的实现:

# Rational.jl
# ...
Rational{T<:Integer}(n::T, d::T) = Rational{T}(n,d)
Rational(n::Integer, d::Integer) = Rational(promote(n,d)...)
Rational(n::Integer) = Rational(n,one(n))

//(x::Rational, y::Integer) = x.num // (x.den*y) <--- HERE!

# ...
#Rational.jl
# ...

理性的{T这是因为Julia最基本的特性之一:多分派。在Julia中,函数可以有许多方法应用于参数类型的各种组合,当调用函数时,Julia调用与调用它的所有参数类型相匹配的最具体的方法。
/
c您发布的方法定义中的所有内容都以integer integer
/
的形式定义了rational integer,因此它实际上不是递归的,因为该方法不调用自身,而是调用同一“泛型函数”中的不同方法

< P >为了理解在这种情况下多个调度是如何工作的,让我们考虑表达式<代码>(3/4)//6 < /代码>的评估。我们将使用<代码> >宏,以查看每个函数调用调用的方法。< /P>
julia> @which (3//4)//6
//(x::Rational{T<:Integer}, y::Integer) at rational.jl:25
这个方法的定义实际上比您发布的要稍微复杂一些,因为它被修改为检查整数溢出–但本质上是一样的,而且更容易理解更旧、更简单的版本,所以我将使用它。让我们将
x
y
分配给参数,看看定义c是什么方法所有:

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
如您所见,此表达式不调用相同的方法,它调用:

此方法只需调用
Rational
构造函数,该构造函数将
n
d
的比率设置为最低值,并创建一个
Rational
number对象

在朱丽亚中,用函数的另一种方法定义函数的一种方法是很常见的。例如,这就是参数默认值是如何工作的。
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
默认参数语法只生成第二个只包含一个E参数的方法,该方法使用默认值调用两个参数形式。因此
f(x,y=1)=2x^y
完全等同于定义两个方法,其中一元方法只调用二进制方法,为第二个参数提供默认值:

julia> f(x, y) = 2x^y
f (generic function with 1 method)

julia> f(x) = f(x, 1)
f (generic function with 2 methods)

这很清楚,谢谢。
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
julia> f(x, y) = 2x^y
f (generic function with 1 method)

julia> f(x) = f(x, 1)
f (generic function with 2 methods)