Julia 管道运算符适用于涉及乘法但不适用于指数的函数

Julia pipe operator works with function involving multiplication but not with exponentiation

以下代码工作正常:

f(x) = 2*x
[1, 2, 3] |> f

但是,下面的代码失败了:

g(x) = x^2
[1, 2, 3] |> g

Closest candidates are:
  ^(::Union{AbstractChar, AbstractString}, ::Integer) at strings/basic.jl:718
  ^(::Complex{var"#s79"} where var"#s79"<:AbstractFloat, ::Integer) at complex.jl:818
  ^(::Complex{var"#s79"} where var"#s79"<:Integer, ::Integer) at complex.jl:820
  ...
Stacktrace:
 [1] macro expansion
   @ ./none:0 [inlined]
 [2] literal_pow
   @ ./none:0 [inlined]
 [3] g(x::Vector{Int64})
   @ Main ./REPL[17]:1
 [4] |>(x::Vector{Int64}, f::typeof(g))
   @ Base ./operators.jl:858
 [5] top-level scope

这与管道运算符完全无关:

julia> [1, 2, 3] * 2
3-element Vector{Int64}:
 2
 4
 6

julia> [1, 2, 3] ^ 2
ERROR: MethodError: no method matching ^(::Vector{Int64}, ::Int64)

如果你想对容器中的每个元素应用一个操作,你应该使用 broadcasting (see also https://julialang.org/blog/2017/01/moredots/)

julia> [1, 2, 3] .* 2
3-element Vector{Int64}:
 2
 4
 6

julia> [1, 2, 3] .^ 2
3-element Vector{Int64}:
 1
 4
 9

[1, 2, 3] * 2 有效的事实是因为向量乘以标量是一种数学运算,而向量乘以标量 ([1, 2, 3] ^ 2) 则不是。

除了@fredrikekre 的回答,我还想提一下以下作品:

g(x) = x^2
[1, 2, 3] .|> g

为广播添加一个额外的点可以达到目的,并允许使用管道运算符,从而将集合提供给管道并输出集合。

另一种使广播运算符对整个管道产生影响的方法是使用 @. 宏:

f(x) = 2x
g(x) = x^2
@. [1, 2, 3] |> f |> g