阅读本文大约需要2.33分钟.

前言

熟悉 C++/Java/Kotlin 等能够OOP语言的人都知道我们可以对成员函数用点操作符来调用成员函数, 而 Kotlin (以及一些语言比如Scala, JavaScript, C# 等, 欢迎补充)就绝了, 可以把 不是成员函数的东西通过语法糖的方式, 一般是叫扩展函数, js 毕竟函数一等公民, 叫prototype. 第一个参数指明 receiver(this), 然后调用.

然后

但是 Julia 语言是靠多重派发的, 怎么玩? 熟悉 Julia 语言的都知道, 都是一个个函数的形式. 很多函数第一个参数是本身, 然后才开始操作 , 好像没有专门的语法糖搞这个啊. 但是有一个管道操作符 |>, 对于如果只有一个参数的函数, 可以直接这么用. 算是一种妥协吧

julia> arr=[1,2,3]
julia> f(x)=2x+1
julia> arr |> join
"123"

这样的话, 单参数的问题似乎解决了. 那么多个参数怎么办呢?

似乎可以用 lambda (箭头函数)来搞定:

julia> arr=[1,2,3]
julia> f(x)=2x+1
julia> arr |> it -> join(it, " ") # join 的时候用空格

但是这样也太不优雅了点! 这个时候居然还要我传递参数…

Meta Programming

众所周知(划掉), Julia 是可以搞元编程的. 我们可以用宏来解决上面的问题. (Roger 说宏能够获取到的信息有限, 但是我们只是做玩具, 所以不要在意这些…)

所以我们就开始干了:

macro extfun(n)
    name = string(n.args[1])
    param = n.args[2]
    if typeof(param) == String
        param = "\"$param\""
    end
    before, after = stringbetweenlast(name,'.') # 这可能真的是 Julia 函数的 "命名风格"
    expression = "$(after)($(before), $(param))"
    eval(Meta.parse(expression))
end
#= 
stringbetweenlast 函数实现略, 我是先获取到最后一个 . 的位置然后切片~
为什么会有这个函数, 因为"宏能够获取到的信息有限"啊! 谁知道 n.args[1] 这玩意居然会给我返回 `:(arr.join)`这种东西, 惹不起惹不起.
=#

最后就是这么愉快地调用了~
@extfun arr.join("/")

你也可以这么用

最后

温馨提示: 这玩意自己玩玩就好, 只要不是一个人的工程真这么写可能会被人打死的~( TロT)σ~ 而且这么写可能会让有函数参数智能提示的 编辑器/IDE 不知所措(放心, 我们现在函数参数提示的对齐还没做, 现在又有新的不做的理由了23333)