Kotlin四匿名函数

1.函数的声明

  kotlin中函数的声明和java中有所不同。

  1)得有fun关键字修饰,

  2)参数的声明方式和变量声明类似 age:Int,先写参数名,后面跟着参数类型

  3)返回值类型写在参数的后面。

//可见性修饰符  函数关键字 方法法名     参数名 参数类型          返回值
private       fun      functionName(age: Int, name: String): String {

    return name + age;
}

2.函数参数

   默认值参:如果不打算传入值参,可以预先给参数设定默认值

fun main() {
    //通常调用方式
    fix("xiaohua", 20)
    //age已经给定默认值,此时可以不传参数
    fix("xiaohua")
}

//参数age 给定默认值
fun fix(name: String, age: Int = 18) {
    println(name + age)
}

 3.Unit函数

   Kotlin中没有返回值的函数叫Unit函数,也就是说他们的返回值是Unit

   可以打印一下上面定义的fix函数。打印的值是kotlin.Unit。

  println( fix("xiaohua"))

4.匿名函数:定义时不取名字的函数,被称为匿名函数。

 1)具名函数的声明:会显示的使用fun关键字修饰。

//具名函数
fun sayHello(): String {
    return "Hello world!"
}

fun main() {
    //具名函数调用
    println(sayHello())
}

匿名函数:

1)匿名函数虽然没有名字,但是可以赋值给变量,这个变量的类型就是函数类型。就像其他变量赋值那样。

2) 和具名函数不一样,匿名函数通常不需要return关键字返回数据。匿名函数会隐式的或自动返回最后一行代码的执行结果。

普通变量赋值:

 val hello: String = "hello"

匿名函数赋值变量:

fun main() {
    //声明一个匿名函数,并赋值给变量sayHello
    val sayHello: () -> String = {
        "Hello world!"
    }
    
    //匿名函数调用
    println(sayHello())
}

3)匿名函数类型。

     普通变量的类型在赋值时就指定了,或者通过类型推断,由编译器在编译器指定变量类型。

     那么匿名函数的类型是啥,由啥决定?

     匿名函数的类型是由参数和返回值决定的。

fun main() {
    //声明一个匿名函数,并赋值给变量sayHello
    val sayHello: () -> String = {
        "Hello world!"
    }
    //打印函数变量
    println(sayHello)
}

得到的结果是Function0<java.lang.String>

Function0:Function后的数字表示的是参数的个数,0表示无参,1表示一个参数,以此类推。

<java.lang.String> 表示的是匿名函数返回值类型。

5.匿名函数的参数:

  匿名函数可以不带参数,也可以带一个参数或多个参数。

  需要带参数时,参数类型放在匿名函数的类型定义中“()”,参数名放在函数定义中“{}”。

1)一个参数的定义:

fun main() {
    val sayHello: (name: String) -> String = { name ->
        "Hello $name!"
    }
    println(sayHello("HanMei"))
}

  当匿名函数的参数只有一个时,可以使用it关键字来表示参数名。当有多个参数时就不能使用了。

fun main() {
    val sayHello: (name: String) -> String = {
        "Hello $it!"
    }
    println(sayHello("HanMei"))
}

2)定义多个参数的匿名函数

fun main() {
    val sayHello: (String, Int) -> String = { name, age ->
        "Hello $name$age"
    }
    println(sayHello("HanMei",18))
}

3)类型推断。

    我们知道定义普通变量时,在编码阶段可以不用给变量指定类型。

    当我们把匿名函数赋值给变量时,也可以不用指定函数的返回值类型,有编译器进行类型推断。

 这时定义匿名函数时的“: () -> String”都可以省略。

  无参数时的类型推断:

fun main() {
    val sayHello = {
        "Hello world!"
    }
    println(sayHello())
}

一个参数的类型推断:

  参数定义和返回值定义可以省略。但是必须在函数定义中,指定参数类型和参数名。

fun main() {
    val sayHello={ name:String ->
        "Hello $name!"
    }
    println(sayHello("HanMei"))
}

多个参数的类型推断:

fun main() {
    val sayHello = { name: String, age: Int ->
        "Hello $name$age!"
    }
    println(sayHello("HanMei", 18))
}

6.lambda表达式:

我们将匿名函数称为lambda函数。将他的定义称为lambda表达式,他的返回结果称为lambda结果

7.定义参数是匿名函数的函数:函数的参数是另外一个匿名函数。

     1)先定义一个具名函数,接收一个匿名函数为参数。

//定义一个具名函数,接收一个String参数和一个函数参数happyNewYear
//happyNewYear: (name: String, year: Int) -> String 这个就是匿名函数的定义
fun sayhello(name: String, happyNewYear: (name: String, year: Int) -> String) {
    val year = 2022
    //在具名函数中调用传递进来的匿名函数
    println(happyNewYear(name,year))
}

 2)定义一个匿名函数,调用具名函数时,当作参数传递过去。


fun main() {
    //定义一个匿名函数
    val happyNewYear = { name: String, year: Int ->
        "${name},happy ${year}!"
    }
    //调用具名函数,并把匿名函数当作参数传递
    sayhello("HanMei", happyNewYear)
}

3)上面的匿名函数可以不单独定义,也可以在调用时定义实现。

  这种写法和java中的匿名内部类是不是很像。方法的参数new一个接口,实现接口中的方法。

fun main() {

    sayhello("HanMei", happyNewYear = { name: String, year: Int ->
        "${name},happy ${year}!"
    })

}

4)如果lambda是一个函数的最后一个参数,或者是唯一的参数。那么,括住lambda值参的一对圆括号可以去掉。

fun main() {

    sayhello("HanMei") { name: String, year: Int ->
        "${name},happy ${year}!"
    }
}

8.匿名函数,还可以用于扩展Kotlin的内置函数。

count是Kotlin用于计算字符串长度的内置函数。

  val word = "HappyNewYear"
  var count = word.count()

用匿名函数进行扩展

    count =  word.count({ letter ->
        letter == 'a'
    })

我们知道:当函数的最后一个参数或只有一个参数是lambda时,那对圆括号可以省略

count =  word.count { letter -> letter == 'a' }

我们又知道,当参数只有一个时,可以用it代替

count = word.count { it == 'a' }

9.函数的引用

要把函数作为参数传递给其他函数,除了lambda表达式,kotlin还提供了其他方法--函数引用

函数引用可以把一个具名函数转换成一个值参,传递给其他函数。

使用lambda表达式的地方,都可以使用函数引用。

1)首先定义两个具名函数:

happyNewYear就是一个普通函数。

sayhello可以接收一个函数参数。这个函数参数可以接收一个匿名函数,也可以接收一个函数引用。

fun happyNewYear(name: String, year: Int): String {
    return "$name happy $year"
}

fun sayhello(name: String, happyNewYear: (name: String, year: Int) -> String) {
    val year = 2022
    println(happyNewYear(name, year))
}

2) 函数引用的使用:双冒号+函数名,就是这个函数的引用,可以当做值参传递

fun main() {
    //::happyNewYear这个就是函数的引用,
    sayhello("HanMei",::happyNewYear)
}

10.函数类型作为返回类型

    一个函数的返回值,可以是另外一个函数,函数类型也是有效的返回值类型。

sayhello是一个无参的方法,返回值类型是(String) -> String,这个表达的意思就是一个参数为String类型,返回值为String类型的匿名函数。

fun sayhello(): (String) -> String {
    return {
        val year = 2022
        "$it happy $year"
    }
}

调用方法:

fun main() {
    //调用sayhello得到这个匿名函数,并赋值给变量happyNewYear
    val happyNewYear = sayhello();
    //happyNewYear就是一个匿名函数,可以直接传参调用
    println(happyNewYear("HanMei"))
}

注意上面的返回匿名函数有这样一句代码, val year = 2022;这个是定义在匿名函数中的。

也可以定义在外边的具名函数中,匿名函数仍然可以访问的到。

fun sayhello(): (String) -> String {
    val year = 2022
    return {
        "$it happy $year"
    }
}

这就是另外一个概念。闭包

在Kotlin中,匿名函数,能修改并引用定义在自己作用域之外的变量,匿名函数引用着定义自身的函数里的变量。也就是说sayhello返回的匿名函数,可以引用定义它的函数sayhello的变量。

Kotlin的lambda就是闭包。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340