Julia 作为不带管道的中缀运算符的函数?

Julia 作为不带管道的中缀运算符的函数?,julia,Julia,在阅读一本关于Julia的书时,我发现了以下代码示例: 作者创建了一个类型 type Student name::String end 创建此类型的实例 antony = Student("Antony Miller") 然后用两种不同的方法测试antony的类型 isa(antony, Student) true antony isa Student true 这是一种很棒的使用语法使代码可读的方法。但是,这里如何启用函数isa()作为中缀运算符?我会猜到以下是可能的 anto

在阅读一本关于Julia的书时,我发现了以下代码示例:

作者创建了一个类型

type Student
    name::String
end
创建此类型的实例

antony = Student("Antony Miller")
然后用两种不同的方法测试antony的类型

isa(antony, Student)
true

antony isa Student
true
这是一种很棒的使用语法使代码可读的方法。但是,这里如何启用函数
isa()
作为中缀运算符?我会猜到以下是可能的

antony |> isa(Student)
true

…因为管道(
|>
)使用左边的对象作为右边函数的第一个参数。但是,为什么在下面的示例中可以省略管道呢?我能在我自己的函数中也使用同样的行为来提高代码的可读性吗(我真的希望如此)?

正如这个答案中所解释的:,Julia有一组固定的中缀运算符。可以重载运算符,但不允许定义新的中缀运算符

isa
在这组预定义的中缀运算符中


但是,可以使用宏模拟中缀运算符(链接线程中也指出了这一点)。您可以在中看到一个示例。

可以使您要求的管道语义生效。假设我们有两个参数的函数

rel_diff(x, y) = (x - y)/(x + y) 
我们可以定义

rel_diff(y) = x -> rel_diff(x, y)
所以

julia> 1 |> rel_diff(2)
-0.3333333333333333
我不认为这在美学上很令人愉悦,但你可能会


另一种选择是这个技巧:

struct Infixed{X, F <: Function}
    x::X
    f::F
end

(|)(args...) = Base.:(|)(args...)
(|)(x, f::Function) = Infixed(x, f)
(|)(xf::Infixed, y) = xf.f(xf.x, y)

请注意,这依赖于隐藏
|
的基本定义,以便我们不会提交类型盗版。如果您已经使用了
|
,那么这在全局作用域REPL中不起作用,但是如果您使用
let
或在函数体内部创建一个新的局部作用域,它就会起作用。

您可以向管道提供lambda,不是吗?不确定为什么需要检查代码内部的类型,多重分派将更加强大和简洁, imo@Evgeny这篇文章不是关于检查类型的。它是关于在没有管道的情况下使用函数作为中缀运算符。如果您想了解更多,通常会调用这种方法。它在函数式语言中被大量使用。
julia> 1 |rel_diff| 2
-0.3333333333333333