美文网首页
函数类型

函数类型

作者: 一江碎月 | 来源:发表于2018-07-25 14:06 被阅读0次

用于指定该参数接收一个函数或者一个 lambda 表达式。

声明

用小括号将参数类型括起来,后跟 ->,最后是返回值类型。如下:

(Int,String, Int) -> Unit

它表示该函数接收三个参数,类型分别是 int,string,int,返回值类型为 Unit。因此,下面定义的函数可以匹配上述的函数类型:

    fun demo(a: Int, b: String, c: Int) 

函数类型的参数可以接收一个 labmda 或 一个函数成员引用,不能直接将函数名传入其中

fun main(args: Array<String>) {
    test(::demo)

    test { a, b, c ->
        println("$a,$b,$c")
    }
}

fun test(action: (Int, String, Int) -> Unit) {
    action(3, "aaa", 2)
}

fun demo(a: Int, b: String, c: Int) {
    println("$a,$b,$c")
}

函数类型接口

函数类型是一种类型,因此函数类型可以做为父类,可以定义实现了某个函数类型的类。

函数类型的子类,必须重写 invoke 方法。该方法的参数类型是函数类型的参数类型,返回值类型是函数类型的返回值类型:

fun main(args: Array<String>) {
    val t = Test()
    println( t("xxx")) // true
    println(t("yii")) // false
}

class Test : (String) -> Boolean {
    override fun invoke(p1: String): Boolean = p1.contains("xx")
}

在编译后,函数类型会转成 Function 的子类,而 Function 中定义了 invoke 方法,所以子类必须实现 invoke 方法。

而且根据 invoke 约定,可直接使用像调用函数一样调用子类实例。如上述的 t("xxx")。


实质

函数类型在编译后都会转成 FunctionN<P1,P2,...,PN,R> 的子类。其中 P1 到 PN 表示函数类型的参数类型,R 表示返回值类型。因此,(T)->R 可以认为是 Function1 类的 kt 写法,两者等价。

默认值

函数类型也是一种类型,因此可以用作函数的形参类型。

kt 的函数中,形参可以指定默认值。因此函数类型的形参也可以指定默认值,其值可以是成员引用,也可以是 lambda:

fun main(args: Array<String>) {
    println(demo())
    println(demo2())
}

fun test() = "aa"

fun demo(a: () -> String = { "lambda" }) = a()
fun demo2(a: () -> String = ::test) = a()

作为参数,表达式有可能为 null,只要对应的变量声明为可空类型。而 java 调用含 lambda 的函数时,在对应的位置上传递的是 FunctionN 的实例。 而 FunctionN 中定义了 invoke 方法,因此可以 结合 FunctionN 与安全调用,避免对参数的空判断

fun test(a:((Int)->String)?){
    if(a != null)
        println(a(2))
}

fun test2(a:((Int)->String)?){
    println(a?.invoke(3)) // 直接调用 invoke 方法,相当于执行了表达式
}

test() 方法中进行空判断,然后调用;test2 中,使用安全调用 invoke 方法。


在 java 中使用

在 java 中调用含有函数类型参数的函数时,需要显式地传入一个 FunctionN 的实例。

一个函数类型的变量是 FunctionN<> 接口的一个实现。其中 N 表示函数需要的参数个数,泛型依次为参数类型及返回值类型。

FunctionN 中有一个 invoke 方法,该方法中可以写入 lambda 的主体。

如下,调用函数类型为 (Int)->Unit 的 test 函数时,需要传入一个 Function1 的实例。因为表达式需要返回一个 Unit 类型的实例,该类型的实例只有 Unit.INSTANCE 一个,因此在 Java 中调用时需要显式返回:

        DemoKt.test(new Function1<Integer, Unit>() {
            @Override
            public Unit invoke(Integer integer) {

                return Unit.INSTANCE;
            }
        });

相关文章

  • Swift5-外行零基础入门_12-函数(下)

    函数 函数类型作为参数类型,函数类型作为返回类型,嵌套函数 函数类型 关于数据类型,我们之前已经介绍过了。现在来回...

  • TypeScript 函数

    TypeScript 函数 函数类型 为函数定义类型 使用这种方式,为函数定义返回的类型 书写函数类型 书写函数类...

  • 函数类型与闭包

    函数类型 函数类型定义:(参数类型1,参数类型2,……)->返回值类型 函数类型是一种引用类型,类似于函数指针。可...

  • Swift探索(七): 闭包

    一:函数类型 每个函数都有种特定的函数类型,函数的类型由函数的参数类型和返回类型组成。 上述代码中 (Double...

  • TypeScript学习-- 函数(1)

    TypeScript 函数(1) tsc greeter.ts 函数类型 为函数定义类型 书写完整函数类型 函数...

  • 四、函数进阶

    一. 高阶函数 参数类型包含函数类型或返回值类型为函数类型的函数为高阶函数。 常见的高阶函数 高阶函数的调用 二....

  • 每天学一点Swift----函数(二)

    三.函数类型 1. Swift的每个函数都有类型的,函数类型由函数的形参列表,返回值类型组成。 2.使用函数类型定...

  • Swift 学习笔记 - 函数与闭包

    函数 使用函数类型 (Using Function Types) 函数类型作为参数类型 (Function Typ...

  • 函数

    普通定义 为函数定义类型 完整的函数类型 函数类型包含两部分:参数类型返回值类型 推断类型 函数定义时,如果赋值语...

  • iOS开发 - 「Swift 学习」Swift 函数(函数类型定

    Swift 函数类型及使用 函数都有特定的函数类型,由函数的参数类型及返回类型组成 函数定义 使用关键字 func...

网友评论

      本文标题:函数类型

      本文链接:https://www.haomeiwen.com/subject/guupmftx.html