定义时不取名字的函数,我们称之为匿名函数,匿名函数通常会将整体传递给其他的函数,
或者从其他函数返回。
匿名函数对Kotlin来说很重要,我们能根据需要制定特殊规则的函数。
//判断里面有多少个s
val totals: Int = "PanamaCanal".count() { letter ->
letter == 'n'
}
val total: Int = "PanamaCanal".count()
println("$totals \n")
println(total)
匿名函数也有类型,匿名函数可以当作变量赋值给函数类型的变量,就像其他变量一样。变量有类型,变量可以等于函数,函数也会有类型。函数的类型,由传入的参数和返回值类型决定。
和具名函数不一样,除了极少数情况外,匿名函数不需要return关键字来返回数据,匿名函数会隐式或自动返回函数最后一行语句的结果。
//创建一个类型是一个匿名函数的常量 一下两种写法都可以
val blessingFunction: () -> String = {
val holiday = "New year."
"Happy $holiday \n"
}
blessingFunction={
val holiday="New year."
"Happy $holiday"
}
和正常函数一样,匿名函数可以不带参数,也可以带一个或多个任意类型的函数,需要带函数时,参数的类型放在匿名函数的类型定义中,参数名则放在函数定义中
// 参数 返回值类型
val blessingFunctionIn: (String) -> String ={
// 参数名
name-> var holiday="play games."
"$name happy $holiday"
}
定义只有一个参数的匿名函数时,可以使用it关键字来表示参数,当你需要传入多个值参时,
it关键字就不能使用了。
定义一个变量时,如果已把匿名函数作为变量赋值给他,就不需要显示指明变量类型了。
我们将匿名函数称为lambda,将他的定义称为lambda表达式。
fun main() {
val getDiscountWords={
goodsName:String,hor:Int->
val currencyYear=2021
" \n ${currencyYear}年,双11${goodsName}促销倒计时: $hor 小时"
}
showOnGog("电脑",getDiscountWords);
}
//shuffled 随机排序 last 取其中一个
inline fun showOnGog(goodsName:String, getDiscountWords:(String,Int)->String){
val hour=(1..60).shuffled().last()
print(getDiscountWords(goodsName,hour))
}
如果一个函数的lambda参数排最后,或者是唯一的参数,那么括住lambda值参的一对圆括 号就可以省略。
fun main() {
showOnGog("电脑"){
goodsName:String,hor:Int->
val currencyYear=2021
" \n ${currencyYear}年,双11${goodsName}促销倒计时: $hor 小时"
};
}
//shuffled 随机排序 last 取其中一个
inline fun showOnGog(goodsName:String, getDiscountWords:(String,Int)->String){
val hour=(1..60).shuffled().last()
print(getDiscountWords(goodsName,hour))
}
在JVM上,你定义的lambda会以对象实例的形势存在,JVM会为所有同lambda赋值的变量分配内存,这就产生了内存开销。lambda的内存开销会带来严重内存问题,而内联可以避免,使用内联JVM就不需要使用lambda对象实列了,哪里使用了lambda,编译器就会将函数体复制到哪里。
使用lambda的递归函数无法使用内联,因为会导致复制粘贴无限循环,编译也会报错。
要把函数作为参数传给其他函数使用,除了传lambda表达式,kotlin还提供方法,传递函数引用,函数引用可以把一个具名函数转换成一个值参,使用lambda表达式的地方,都可以使用函数引用。
fun main() {
//要获得函数引用,使用::操作符,后跟要引用的函数名
showOnGog("卫生纸",:: getDiscountWords);
}
private fun getDiscountWords(goodsName: String ,hour: Int) :String {
val currencyYear=2021
return " \n ${currencyYear}年,双11${goodsName}促销倒计时: $hour 小时"
}
//shuffled 随机排序 last 取其中一个
inline fun showOnGog(goodsName:String, getDiscountWords:(String,Int)->String){
val hour=(1..60).shuffled().last()
print(getDiscountWords(goodsName,hour))
}
函数类型也是有效的函数类型,也就是说可以定义一个能返回函数的函数
fun main() {
val configDiscountWords = configDiscountWords()
print(configDiscountWords("沐浴露"));
}
fun configDiscountWords():(String)->String{
return {
goodsName:String->
val currencyYear=2021
val hor=(1..24).shuffled().last()
" \n ${currencyYear}年,双11${goodsName}促销倒计时: $hor 小时"
}
}
在Kotlin中,匿名函数能修改并引用定义在自己的作用域之外的变量,匿名函数引用着定义自身的函数里的变量,Kotlin中的lambda就是闭包
能接收函数或者返回函数的函数又叫做高级函数,高级函数广泛应用与函数式编程
函数类型能让开发者少写模式化代码,写出更灵活代码。Java 8支持lambda表达式,但不支持将函数作为参数传给一个函数或变量,不过java的代替方案是匿名内部类。
public static void main(String[] args) {
showOnBoard("卡带",(goodsName, hour) -> {
int currentYear=2021;
return String.format("%s年,双11%s促销倒计时:%d 小时",currentYear,goodsName,hour);
});
}
public interface DiscountWords{
String getDiscountWords(String goodsName,int hour);
}
public static void showOnBoard(String goodsName,DiscountWords discountWords){
int hour=new Random().nextInt(24);
System.out.println(discountWords.getDiscountWords(goodsName,hour));
}
下一篇: Kotlin基础 空安全与异常