美文网首页
kotlin语法之将函数作为参数

kotlin语法之将函数作为参数

作者: 聪明叉 | 来源:发表于2019-05-06 20:23 被阅读0次

一个setOnClickListener的错误

写了个demo,点击事件离奇的不生效,非常困扰。

开始实在是看不出有什么问题,错误代码如下:

findViewById<Button>(R.id.btn).setOnClickListener {
    View.OnClickListener {
        ...
    }
}

运行不报错,就是不触发OnClickListener中的代码。

那么正确的写法应该是怎样呢?

如下所示:

// 写法1:OnClickListener写法
findViewById<Button>(R.id.btn).setOnClickListener(
        View.OnClickListener {
            ...
        }
)

或者这样:

// 写法2:闭包写法
findViewById<Button>(R.id.btn).setOnClickListener {
    ...
}

为什么那个错误的写法不报错但是却不能正确运行呢?

因为错误的写法实际上是在写法2的闭包里面又声明了一个OnClickListener,仅仅声明listener当然不能调用里面的代码了。

将函数作为参数传递

为什么setOnClickListener有两种写法呢?

实际上这里setOnClickListener这个方法有两个重载:

// 参数是OnClickListener对象
fun setOnClickListener(l: View.OnClickListener?)
// 参数是闭包
fun setOnClickListener(l: (v: View) -> Unit)

因为有两个重载方法,setOnClickListener才可以有两种写法。

所谓闭包:

在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

kotlin中的闭包一般称为lambda表达式,详细内容可以查看:

高阶函数与 lambda 表达式

我们这里只看将函数作为参数传递的用法。

因为闭包这一特性的存在,上面setOnClickListener才可以不使用传统的OnClickListener, 下面我们自己定义一个简单的例子来说明。

传统写法:

// 声明listener
interface TestListener {
    fun test()
}

// 声明使用listener作为参数的方法
private fun setListener(listener: TestListener) {
    // 调用listener的test方法
   listener.test()
}

// 方法中使用
fun main(){
    setListener(object : TestListener {
        override fun test() {
            Log.i("test_tag", "test Listener")
        }
    })
}

闭包写法:

// 声明方法
private fun setListener(listener: () -> Unit) {
    // 调用传入的方法
    listener()
}

// 方法中使用
fun main(){
    setListener { Log.i("test_tag", "test unit") }
}

明显简化了许多,再也不需要通过声明接口设置监听了。

需要额外说明将函数作为参数传递使用的几种变种:

带参数的闭包:

// 带参数
private fun setListener(l: (c: Context) -> Unit) {
    l(applicationContext)
}
// 使用,只有一个参数时,可以用it代替传入的参数
setListener { Toast.makeText(it, "test param", Toast.LENGTH_SHORT).show() }

带参数且有返回值:

private fun setListener(l: (c: Context) -> Boolean) {
    val b = l(applicationContext)
    Toast.makeText(applicationContext, if (b) "当前时间是偶数" else "当前时间是奇数", Toast.LENGTH_SHORT).show()
}

// 使用,只有一个参数时,可以用it代替传入的参数
setListener {
    Toast.makeText(it, "test param", Toast.LENGTH_SHORT).show()
    // 当前时间是否是偶数
    System.currentTimeMillis() % 2 == 0L
}

相关文章

  • kotlin语法之将函数作为参数

    一个setOnClickListener的错误 写了个demo,点击事件离奇的不生效,非常困扰。 开始实在是看不出...

  • Kotlin入门

    Kotlin学习总结,适用入门 基础语法 函数定义 函数定义关键字 fun 参数格式 参数:类型 表达式作为函数体...

  • Kotlin:将函数作为参数传递

    Kotlin是一门与Swift类似的静态类型JVM语言,由JetBrains设计开发并开源。与Java相比,Kot...

  • Kotlin-----方法进阶

    在kotlin中我们将函数作为参数或者返回值的函数叫做高阶函数,也就是使用方法体作为参数的方法叫做高阶方法。 函数...

  • Kotlin中,理解T.()->Unit 、 ()->Unit与

    Kotlin比Java更方便的地方,其中之一是可以将函数作为参数。上面三者都是将函数作为其它函数的参数来使用,其形...

  • Kotlin中,理解T.()->Unit 、 ()->Unit与

    Kotlin比Java更方便的地方,其中之一是可以将函数作为参数。上面三者都是将函数作为其它函数的参数来使用,其形...

  • kotlin 常用语法

    kotlin的基础语法 函数定义 函数定义使用关键字 fun,参数格式为:参数 : 类型 可变长参数函数 函数的变...

  • Kotlin高阶函数进阶

    Kotlin函数可以作为参数传递吗? 答案是可以的。但是我们知道kotlin的这种特性其实也是一种语法糖,它并不能...

  • Android Kotlin 将函数作为参数传递

    Kotlin支持函数作为参数传递,无需构建对象来包装函数。 1、调用一个无返回的函数作为参数传递为:方法名()->...

  • Kotlin学习

    kotlin基础 kotlin入口及函数定义 函数定义使用关键字 fun,参数格式为:参数 : 类型 表达式作为函...

网友评论

      本文标题:kotlin语法之将函数作为参数

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