复合函数有什么用呢?可以简单解释为,一个函数的参数是另一个函数,直接用另一个函数完成这个复合的功能。
还是看个例子吧。先写两个函数
val add5 = {i:Int -> i + 5}
val multiplyBy2 = {i:Int -> i * 2}
一个实现了加法,一个实现了乘法。调用如下
println(multiplyBy2(5))
println(add5(3))
我们也可以这样
println(multiplyBy2(add5(3)))
把 add5 之后的结果,再进行 multiplyBy2 运算。
只是这样写,如果调用的地方多了似乎比较麻烦啊!这时候就可以写一个复合函数了。
infix fun <P1,P2, R> Function1<P1,P2>.andThen(function:Function1<P2, R>):Function1<P1, R>{
return fun (p1:P1):R{
return function.invoke(this.invoke(p1))
}
}
infix 是中缀修饰符,方便调用的。
fun <P1,P2, R> 中P1,P2是参数,R是返回值。
Function1<P1,P2>中 P1是参数,P2是返回值。这里的Function1表示传入的参数是个Function。
andThen是Function1的扩展。
参数就是 Function1函数。
返回值也是Function1函数。
这个函数的调用是这样的
val add5AndMultiplyBy2 = add5 andThen multiplyBy2
println(add5AndMultiplyBy2(3))
调用的关键,就是那个扩展函数名。
这个名字(andThen)按照我们的喜好来定义就可以。
先运行一下看结果。
10
8
16
16
再写一个同样通能的,换个名字看看。
infix fun <P1,P2, R> Function1<P1, P2>.jiXuZuo(function: Function1<P2, R>):Function1<P1, R>{
return fun(p1:P1):R{
return function.invoke(this.invoke(p1))
}
}
然后这样调用
val addJiXuZuoMultiplyBy2 = add5 jiXuZuo multiplyBy2
println(addJiXuZuoMultiplyBy2(3))
运行结果也是 16
只是,这种调用有点不走寻常路,是吗?这就是 infix 的妙用。如果你去掉它,就要像一般的函数那样调用了。
我们再写一个一样功能的函数,但是不加 infix
val addJiXuZuoMultiplyBy2 = add5 jiXuZuo multiplyBy2
println(addJiXuZuoMultiplyBy2(3))
它的调用就不同了,要这样写
val addFuheMultiplyBy2 = add5.fuhe(multiplyBy2)
println(addFuheMultiplyBy2(3))
这样是不是就很熟悉了?
也不仅仅是 Int,其他类型也是可以这样写复合函数的。下面用 String 再调用一下。
val myname = { str: String -> "my age is " + str }
val age = { i: String -> i }
在 main 里这样写
println(age(myname("six")))
val mynameAndAge = age jiXuZuo myname
println(mynameAndAge("seven"))
运行的结果是
my age is six
my age is seven
在处理P1,P2的时候,千万别弄错顺序哦。不然结果就完全不同了。当然,String 类型好像没这种烦恼。
网友评论