函数进阶

操作符也是函数

大多数操作符只不过是支持特殊语法的函数( &&|| 等除外,它们不能是函数,因为短路求值要求在计算整个表达式的值之前不计算每个操作数)

julia> +(1, 2, 3)
6

中缀表达式和函数形式完全等价。—— 事实上,前一种形式会被编译器转换为函数调用。这也意味着你可以对操作符进行赋值和传参,就像其它函数传参一样,然而,函数以 f 命名时不再支持中缀表达式

julia> f = +; f(1, 2, 3)
6

具有特殊名称的操作符

有一些特殊的表达式对应的函数调用没有显示的函数名称
表达式函数调用
[A B C ...]hcat
[A; B; C; ...]vcat
[A B; C D; ...]hvcat
A'adjoint
A[i]getindex
A[i] = xsetindex!
A.ngetproperty
A.n = xsetproperty!

函数的复合与链式调用

函数的「复合」指通过运算符 \circ)把多个函数绑定到一起,然后作用于最先调用那个函数的参数,如(f ∘ g)(args...) 等价于 f(g(args...))

julia> (sqrt ∘ +)(3, 6)
3.0

在 1.6 以前,这个运算符会返回匿名函数,而 1.6 及以后会返回 ComposedFunction 实例

函数的「链式调用」指把一个函数作用到前一个函数的输出上,也称为「管道」

julia> 1:10 |> sum |> sqrt
7.416198487095663

它的复合写法是 (sqrt ∘ sum)(1:10)

. 运算符可以进行向量化操作,它也可以与 |> 连用

允许调用非函数

通过特殊的语法,你可以定义对于指定类型的实例的调用

julia> struct T end

julia> (::T)()=0

julia> T()()
0

参阅