IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin基础语法 十二、lamdba表达式解析三(函数类型) -> 正文阅读

[移动开发]Kotlin基础语法 十二、lamdba表达式解析三(函数类型)

前言

因为在kotlin的官网中,对lamdba的介绍篇幅有限而且没有逻辑, 所以在我最初开始接触kotlin的时候,我对kotlin的lamdba表达式有非常多的困惑,为此我花了接近一天的时间,浏览了网上几十篇的文章,才慢慢总结整理了kotlin的lamdba表达式知识点,其中关于 函数类型 讲的最清楚直白的应该是 扔物线 大神的一篇文章:
【码上开学】Kotlin 的高阶函数、匿名函数和 Lambda 表达式
建议对 Lambda 表达式函数类型迷茫的同学去看一下这篇文章,你会感到豁然开朗。
本篇文章只是我自己顺着大神文章的思路和自己理解简单记录的知识点供自己查看,个人强烈推荐原文章。

一、函数类型的由来

在 Java 里,如果你有一个 a 方法需要调用另一个 b 方法,你可以直接在a方法的方法体里面调用:
示例:

int b(int params) {
    return params;
}
int a() {
    return b(1);
}

但这样我们无法动态的传递参数给b方法,
如果我们想在 a 方法调用时动态设置 b 方法的参数,你就得把参数传给 a方法,再从 a 方法的内部把参数传给 b方法,
示例:

int b(int params) {
    return params;
}

int a(int params) {
    return b(params);
}
a(1); // 内部调用 b(1)
a(2); // 内部调用 b(2)

不过……如果我们想动态设置的不是方法参数,而是方法本身呢?比如我在 a 的内部有一处对某个方法的调用,这个方法可能是 b,可能是 c,不一定是谁,我只知道,我在这里有一个调用,它的参数类型是 int ,返回值类型也是 int ,而具体在 a 执行的时候内部调用哪个方法,我希望可以动态设置,
示例:

int a(??? method) {  
return method(1);
}
a(method1);
a(method2);

但是在 Java 里是不允许把方法作为参数传递的,但是确实有一个变通方案:接口。我们可以通过接口的方式来把方法包装起来,

public interface Wrapper {  
int method(int param);
}

然后把这个接口的类型作为外部方法的参数类型:

int a(Wrapper wrapper) {  
return wrapper.method(1);
}

在调用外部方法时,传递接口的对象来作为参数:

a(wrapper1);
a(wrapper2);

在Android 中最典型的例子就是我们的点击事件:所谓的点击事件,最核心的内容就是调用内部的一个 OnClickListener 的 onClick() 方法:

public interface OnClickListener {  
void onClick(View v);
}

而所谓的这个 OnClickListener 其实只是一个壳,它的核心全在内部那个 onClick() 方法。换句话说,我们传过来一个 OnClickListener:

OnClickListener listener1 = new OnClickListener() {  
@Override  
void onClick(View v) {    
doSomething();  
}
};
view.setOnClickListener(listener1);

本质上其实是传过来一个可以在稍后被调用的方法(onClick())。只不过因为 Java 不允许传递方法,所以我们才把它包进了一个对象里来进行传递。

二、Kotlin的函数类型

在 Kotlin 里面,函数的参数也可以是函数类型的,也就是我们可以传递一个函数(其实是函数的对象)给函数作为参数并在方法体内调用。
形式如下:
fun a(funParam: Fun): String {
return funParam(1);
}
当一个函数含有函数类型的参数的时候,如果你调用它,你就可以——当然你也必须——传入一个函数类型的对象给它,
形式如下:
fun b(param: Int): String {
return param.toString()
}
a(b)
当然,上面的两个代码只是形式,真正的kotlin中并不能这么写。

函数类型:用来声明一个函数参数和返回值形式的 特殊数据类型
声明格式如下:
(参数类型列表) -> 返回值类型

因为函数类型可以有各种各样不同的参数和返回值的类型的搭配,这些搭配就形成了不同的函数类型,所以对于函数类型的参数,你要指明它有几个参数、参数的类型是什么以及返回值类型是什么。
例如,无参数无返回值(() -> Unit)和单 Int 型参数返回 String (Int -> String)是两种不同的类型
示例:

fun a(funParam: (Int) -> String): String {  
return funParam(1)
}

同样的,函数类型不只可以作为函数的参数类型,还可以作为函数的返回值类型

fun c(param: Int): (Int) -> Unit {  
...
}

这种参数或者返回值为函数类型的函数,在 Kotlin 中就被称为高阶函数。
*除了作为函数的参数和返回值类型,你把函数类型赋值给一个变量也是可以的。不过对于一个声明好的函数,不管是你要把它作为参数传递给函数,还是要把它赋值给变量,都得在函数名的左边加上双冒号才行:
a(::b)
val d = ::b
*双冒号 ::method 到底是什么?
Kotlin 里「函数可以作为参数」这件事的本质,是函数在 Kotlin 里可以作为对象存在——因为只有对象才能被作为参数传递啊。赋值也是一样道理,只有对象才能被赋值给变量啊。但 Kotlin 的函数本身的性质又决定了它没办法被当做一个对象。那怎么办呢?Kotlin 的选择是,那就创建一个和函数具有相同功能的对象。怎么创建?使用双冒号。
在 Kotlin 里,一个函数名的左边加上双冒号,它就不表示这个函数本身了,而表示一个对象,或者说一个指向对象的引用,但,这个对象可不是函数本身,而是一个和这个函数具有相同功能的对象。

示例:

fun b(number: Int) {
    Log.e("调用了b函数", "----" + number)
}

fun a(number: Int, me: (Int) -> Unit) {
    Log.e("调用了a函数", "----")
    me(number)
}
a(3, ::b)

记住:
双冒号+函数名,表示的不是一个函数,而是一个对象,一个函数类型的对象。

三、匿名函数

要传一个函数类型的参数,或者把一个函数类型的对象赋值给变量,除了用双冒号来拿现成的函数使用,你还可以直接把这个函数挪过来写:
形式如下
a(fun b(param: Int): String {
return param.toString()
});
这种写法的话,函数的名字其实就没用了,所以你可以把它省掉:
a(fun(param: Int): String {
return param.toString()
});
上面两个代码,第一个是不能运行的,因为是一个完整的函数声明,表示的是一个函数,而不是一个对象。而第二个是可以运行的,很神奇,那是因为在kotlin中
一个没有名字的函数其实和 双冒号 表示的意义是一样的,都是函数类型的对象。叫做匿名函数。虽然叫函数但并不是真正的函数而是函数类型的对象。

但我们这么写,会很麻烦并且代码也不美观,所以进一步的简化,就是lamdba表达式的形式了。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:36:39  更:2022-03-30 18:40:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 19:37:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码