Julia函数进阶:匿名函数、函数复合、管道计算

Julia系列:编程初步🔥数组🔥元组、字典、集合

Julia作为科学计算语言,对函数式编程提供了良好的支持,不仅支持匿名函数,还支持管道操作,并且为函数复合提供了运算符,十分强大且便利。

可变参数

有一些函数可以传入任意个数的参数,例如最大值函数

> max(1,2,3)
3

这种机制在Julia中由arg...实现,比如下面定义一个Max函数

function Max(arg...)
    M = -Inf
    for a in arg
        if a > M
            M = a
        end
    end
    return M
end

Max(3,1,4,5)    # 返回5

其逻辑是,把3,1,4,5映射为arg...,则arg自动变成[3,1,4,5],从而可以被迭代。

反过来说,...可以理解为把一个数组展开,效果如下

Max([3,1,4,5])  # 报错!!!
Max([3,1,4,5]...)   # 返回5,等价于Max(3,1,4,5)

匿名函数

目前我们讲了两种定义函数的方法,一种类似于f(x)=x^2,另一种则用function...end来实现,这两种写法均把一段映射和一个名字等同起来了。如果在创建函数时,并不声明函数的名字,那么就相当于创建了一个匿名函数,比如

function (x)
    x^2
end

这个就是匿名函数。当然,这个匿名函数毫无意义,因为没有名字就没法调用,但如果写成如下形式,就可以调用了。

f = function (x)
    x^2
end

f(5)    # 25

在这个过程中,函数名f和函数的实际内容x->x^2被分离开了,相当于把函数当作一个变量赋值给了f,这就是函数式编程的核心思想:函数也是一种变量。

匿名函数还有一种更为简单的写法,这种写法一般也叫做lambda表达式

f = x->x^2
f(5)    # 25

事情到了这个地步,量变也就引起了质变,匿名函数支持一种更加玄幻的写法,即不通过函数名,直接调用

(x->x^2)(5) # 返回25

函数式

函数既然可以被赋值,那么也自然可以作为参数在另一个函数中传递,比如下面写一个函数生成器,用以生成N次方函数

function gen(N)
    x->x^N
end

其输入是一个整数,输出为一个函数,下面测试一下

e5 = gen(5)
e5(3)   # 返回243,即3的5次方

此外,Julia提供了Lisp家族的书写风格,即可以把所有的二元运算改写成函数的形式,示例如下

+(1,2,3)   # 6
*(2, +(3, 5))   # 16, 即2*(3+5)

函数复合

Julia还提供了Ocaml家族的链式风格,用以完成函数复合,比如下面的表达式用于求1,2,3,4,5的均方根

[1:5;] |> (x->x.^2) |> (x->sum(x)/length(x)) |> sqrt 

其中经过三层管道

  1. 对每个元素求平方
  2. 取平均值,由于Base中不提供平均值函数,所以用sum和length自己做了一个
  3. 开根号

管道起到的作用其实是函数的复合,Julia为函数复合提供了运算符,在命令行中可输入\circ然后按下tab键即可,有了这个就可以将上面的三个函数合在一起了,但需要注意,其书写顺序和管道操作|>正好相反,对于f∘g∘h(x)来说,其运算顺序为f(g(h(x))),而对应的管道计算应该表示为x|> h |> g |> f

std = sqrt ∘ (x->sum(x)/length(x))(x->x.^2) 
std([1,2,3,4,5])    # 3.3166247903554
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值