Kotlin 中 Lambda的使用 二、函数类型和实例化

一、函数类型

        在之前我们用到的lambda的语法中val sum: (Int, Int) -> Int = {x: Int, y: Int -> x + y},(Int, Int) -> Int 为函数类型,参数和返回值用 -> 分割开,参数的个数可以是0个或者多个,返回值为空时不可以省略。表示方法可以分为三类。

        1.由一个()括起来的参数列表和用->分割的返回类型

() -> Unit //无参,无返回值的函数类型
(T) -> Unit //接收T类型,无返回值的函数类型
(T) -> R //接收T类型、并且返回R类型值的函数类型
(T, R) -> Unit //接收T和R类型参数无返回值的函数类型
(T, R) -> R//接收T和R类型参数,并且返回R类型值的函数类型

        2.带有接受者的函数类型,比如 A.(B) -> C 表示在接收者对象A上用参数B调用并返回值C的函数。可以直接使用接受者对象的成员(属性和方法),也可以使用this访问其成员。和扩展函数很类似。(kotlin鼓励使用扩展函数,当我们要创建一个用于某个对象的函数时,可以考虑使其成为一个以该对象为接收者的扩展函数。为了尽量减少 API 污染,尽可能地限制扩展函数的可见性。根据需要,使用局部扩展函数、成员扩展函数或者具有私有可视性的顶层扩展函数。)

        带与不带接受者的函数类型可以互换,接收者可以最为第一个参数,反之亦然。例如         (A, B)->C 类型的值可以赋值给接收A.(B)->C类型地方,反之亦然。

fun Person.getNextYearAge2(): Int {
    return age + 1
}
fun getAge(block: (Person) -> Int): Int {
    return block(Person(12, "A"))
}
fun main(args: Array<String>) {
    val age = getAge(Person::getNextYearAge2)
}

        3.挂起函数属于特殊种类的函数类型,它的表示法中有一个 suspend 修饰符 ,例如 suspend () -> Unit或者 suspend A.(B) -> C

        Tips:(1)函数类型可空时使用()?   ((Int,  Int) -> Int)?

                (2)函数类型是右结合的  (Int)-> ((Int) -> Unit)) 等价于  (Int) -> (Int) -> Unit 而不等价于((Int) -> (Int))-> Unit

二、 类型别名 使用关键词 typealias

typealias lambdaAlias = (Int) -> Boolean

 当某个函数类型被多次引用时可以使用函数别名。声明函数类型别名不会产生新的变量

三、函数类型实例化

实例化的函数类型可以作为参数传递到函数中,函数实例化的方式常用的有三种。

(1)使用函数字面值的代码块,lambda表达式或者匿名函数

        lambda表达式 :{a, b -> a+b}

fun getInt(block: (String) -> Int) {
    //...
}
getInt { it.toIntOrNull() ?: 0 }

        匿名函数:fun (s: String): Int { return s.}

fun getInt(block: (String) -> Int) {
    //...
}
getInt(fun(s: String): Int { return s.toIntOrNull() ?: 0 })

        匿名函数可以指定返回类型(大部分情况下lambda返回类型可以自动推到),匿名函数不能写到()外边。一个不带标签的return会在fun关键词声明的函数中返回。因此lambda表达式会在包含他的函数中返回(只有内联函数中才能使用不带标签的retuen),匿名函数中return将会在自身返回。

        (2)使用已有声明的可调用引用

        当我们已经有对应函数类型的函数时,可以使用成员引用将一个函数转换成一个值来传递

  • 顶层、局部、成员、扩展函数:::isOdd、 String::toInt
  • 顶层、成员、扩展属性:List<Int>::size
  • 构造函数:::Regex
fun Person.getNextYearAge2(): Int {
    return age + 1
}

fun getNextYearAge(person: Person): Int {
    return person.age + 1
}

fun getAge(block: (Person) -> Int): Int {
    return block(Person(12, "A"))
}

fun main(args: Array<String>) {
    print("A next year age = ${getAge(::getNextYearAge)}")
    val age = getAge(Person::getNextYearAge2)
}

        (3)使用实现函数类型接口的自定义类的实例

class IntTransformer: (Person) -> Int {
    override fun invoke(p1: Person): Int {
        TODO("Not yet implemented")
    }
}

fun getAge(block: (Person) -> Int): Int {
    return block(Person(12, "A"))
}

fun main(args: Array<String>) {
    print("A next year age = ${getAge(IntTransformer())}")
}

一、入门Lambda表达式在集合函数式API的使用

二、函数类型和实例化

三、SAM转换 (Single Abstract Method Conversions)

四、内联函数 inline​​​​​​​

        

猜你喜欢

转载自blog.csdn.net/old_land/article/details/119541754