我几天前才了解Julia 中的链接函数(如管道) 。今天我尝试了一些事情并得到了意想不到的结果。因此,我决定更好地询问问题的根源,以更好地理解 Julia 在链接函数中的行为。考虑这个例子:
\njulia> a = [1 2 3]\n1\xc3\x973 Matrix{Int64}:\n 1 2 3\n
Run Code Online (Sandbox Code Playgroud)\n然后我想链接一些像下面这样的函数,毕竟我想要整个矩阵的最大值:
\njulia> a .|> x->x^2 .|> sqrt .|> Int64 |> maximum\n1\xc3\x973 Matrix{Int64}:\n 1 2 3\n
Run Code Online (Sandbox Code Playgroud)\n但我期望只有一个3
!为什么 Julia 不考虑链的最后一个函数,即函数maximum
?
PS:另外,我也尝试过这样的方法:
\njulia> a .|> x->x^2 .|> sqrt .|> Int64 |> x->maximum(x)\n1\xc3\x973 Matrix{Int64}:\n 1 2 3\n
Run Code Online (Sandbox Code Playgroud)\n仍然不是我所期望的那样。
\n问题实际上是箭头运算符而不是管道!管道很好。
请记住,如果您想检查解析顺序,则始终可以使用冒号运算符:
julia> :(a .|> x->x^2 .|> sqrt .|> Int64 |> maximum)
:(a .|> (x->begin
#= REPL[84]:1 =#
((x ^ 2 .|> sqrt) .|> Int64) |> maximum
end))
Run Code Online (Sandbox Code Playgroud)
箭头首先评估右侧的所有内容,然后通过管道传输左侧的结果(右关联),因此您所拥有的内容与以下内容相同:
a .|> x->(x^2 .|> sqrt .|> Int64 |> maximum)
Run Code Online (Sandbox Code Playgroud)
在右侧,您只需创建一个函数,将参数(在我们的示例中为单个数字)一直传输到最大值,映射只需执行 3 次即可给出结果。
你想要的是:
a .|> (x->x^2) .|> sqrt .|> Int64 |> maximum
Run Code Online (Sandbox Code Playgroud)
我通常会确保无论何时将箭头与管道一起使用,箭头都用括号括起来 - 否则这是非常违反直觉的!
如果你刚刚做了类似的事情
a .|> sqrt |> maximum
Run Code Online (Sandbox Code Playgroud)
你不会注意到这一点。请注意管道的关联性非常有意义 - 上面是
maximum(sqrt.(a))
Run Code Online (Sandbox Code Playgroud)
正如你所期望的那样。关于右箭头函数的问题是,它无法真正“知道”右侧的函数是什么,因此它只是解析所有内容。