| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Kotlin学习——函数与Lambda表达式 -> 正文阅读 |
|
[移动开发]Kotlin学习——函数与Lambda表达式 |
函数Kotlin中函数使用 fun 关键字声明
参数函数参数使用 Pascal 表示法定义,即 name: type 。参数用逗号隔开,每个参数必须有显式类型。 默认参数:函数参数可以有默认值,当省略相应的参数时使用默认值。与其他语言相比,这可以减少重载数量
覆盖方法总是使用与基类型方法相同的默认参数值。当覆盖一个带有默认参数值的方法时,必须从签名中省略默认参数值。 如果一个默认参数在一个无默认值的参数之前,那么该默认值只能通过使用命名参数调用该函数来使用
命名参数可以在调用函数时使用命名的函数参数。当一个函数有大量的参数或默认参数时这会非常方便
当一个函数调用混用位置参数与命名参数时,所有位置参数都要放在第一个命名参数之前。例如允许调用 f(1, y=2) 但不允许 f(x =1, 2) 可以通过使用星号操作符将可变数量参数( vararg) 以命名形式传入
返回 Unit 的函数如果一个函数不返回任何有用的值,它的返回类型是 Unit。 Unit 是一种只有一个值——Unit 的类型。这个值不需要现式返回,Unit 返回类型声明也是可选的(相当于java中的 void) 单表达式函数当函数返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可
显式返回类型具有块代码体的函数必须始终显式指定返回类型,除非他们想要返回 Unit,在这种情况下它是可以省略的 可变数量的参数(Varargs)函数的参数(通常是最后一个)可以用 vararg 修饰符标记
在函数内部,类型T的 vararg 参数的可见方式是作为 T 数组,即上例中的 ts 变量具有类型 Array<out T> 只有一个参数可以标注为 vararg。如果 vararg 参数不是列表中的最后一个参数,可以使用命名参数语法传递其后的参数的值,或者,如果参数具有函数类型,则通过在括号外部传一个 lambda 当我们调用 vararg -函数时,我们可以一个接一个的传参,如果我们已经有一个数组并希望将其内容传递给该函数,我们使用伸展(spread)操作符(在数组前面加 *)
中缀表示法标有 infix 关键字的函数也可以使用中缀表示法(忽略该调用的点与圆括号)调用。中缀函数必须满足以下要求:
中缀函数调用的优先级低于算术操作符、类型转换以及 rangeTo 操作符;优先级高于布尔操作符 && 与 || 、is- 与 in- 检测以及其他一些操作符 中缀函数总是要求指定接收者与参数。当使用中缀表示法在当前接收者上调用方法时,需要显式使用 this;不能像常规方法调用那样省略,这是确保非模糊解析所必需的
尾递归函数Kotlin支持一种称为尾递归的函数式编程风格。这允许一些通常用循环写的算法改用递归函数来写,而无堆栈溢出的风险。 当一个函数用 tailrec 修饰符标记并满足所需的形式时,编译器会优化该递归,留下一个快速而高效的基于循环的版本
要符合 tailrec 修饰符的条件的话,函数必须将其自身调用作为它执行的最后一个操作。在递归调用后有更多代码时,不能使用尾递归,并且不能用在 try/catch/finally 块中。 高阶函数与 lambda 表达式高阶函数是将函数用作参数或返回值的函数
在上面的代码中,参数 combine 具有函数类型 (R, T) -> R,因此 fold 接受一个函数作为参数,该函数接受类型分别为 R 与 T 的两个参数并返回一个 R 类型的值。在 for-循环内部调用该函数,然后将其返回值赋值给 accumulator 函数类型Kotlin使用类似 (Int) -> String 的一系列函数类型来处理函数的声明:val onClick: () => Unit = ...... 这些类型具有与函数签名相对应的特殊表示法,即它们的参数和返回值:
函数类型表示法可以选择性的包含函数的参数名: (x: Int, y: Int) -> Point。这些名称可用表明参数的含义。 如需将函数类型指定为可空,可以使用圆括号:((Int, Int) -> int)? 函数类型实例化有几种方法可以获得函数类型的实例
函数类型实例调用函数类型的值可以通过其 invoke(....) 操作符调用:f.invoke(x) 或者直接 f(x) 如果该值具有接收者类型,那么应该将接收者对象作为第一个参数传递。调用带有接收者的函数类型值的另一个方式是在其前面加上接收者对象,就好比该值是一个扩展韩式:1.foo(2)
Lambda 表达式与匿名函数lambda 表达式与匿名函数是“函数字面值”,即未声明的函数,但立即做为表达式传递
Lambda 表达式语法Lambda 表达式的完整语法形式如下:
Lambda 表达式总是括在花括号中,完整语法形式的参数声明放在花括号内,并有可选的类型标注,函数体跟在一个 -> 符号之后。如果推断出该 lambda 的返回类型不是 Unit,那么该 lambda 主体中的最后一个(或可能是单个)表达式会视为返回值 传递末尾的 lambda 表达式在 Kotlin 中有一个约定:如果函数的最后一个参数是函数,那么作为相应参数传入的 lambda 表达式可以放在圆括号之外
这种语法也称为拖尾lambda表达式? it: 单个参数的隐式名称一个lambda 表达式只有一个参数是很常见的。如果编译器自己可以识别出签名,也可以不用声明唯一的参数并忽略 ->。该参数会隐式声明为 it
从 lambda 表达式中返回一个值我们可以使用限定的返回语法从 lambda 显式返回一个值。否则,将隐式返回最后一个表达式的值
下划线用于未使用的变量(自1.1起)如果 lambda 表达式的参数未使用,那么可以用下划线取代其名称:
匿名函数上面提供的 lambda 表达式语法缺少的一个东西是指定函数的返回类型的能力,在大多数情况下,这是不必要的。因为返回类型可以自动推断出来。然而,如果确定需要显式指定,可以使用另一种语法:匿名函数 匿名函数看起来非常像一个常规函数声明,除了其名称省略了。其函数体可以是表达式或代码块
匿名函数的返回类型推断机制与正常函数一样:对于具有表达式函数体的匿名函数将自动推断返回类型,而具有代码块函数体的返回类型必须显式指定(或者已假定为 Unit) 注意:匿名函数参数总是在括号内传递。允许将函数留在圆括号外的简写语法仅适用于 lambda 表达式 Lambda 表达式与匿名函数之间的另一个区别是非局部返回的行为。一个不带标签的 reutrn 语句总是在用 fun 关键字声明的函数中返回。这意味着 lambda 表达式中的 return 将从包含它的函数返回,而匿名函数中的 retun 将从匿名函数自身返回 闭包Lambda 表达式或者匿名函数(以及局部函数和对象表达式)可以访问其闭包,即在外部作用域中声明的变量。在 Lambda 表达式中可以修改闭包中捕获的变量:
带有接收者的函数字面值带有接收者的函数类型。例如 A.(B) -> C,可以用特殊形式的函数字面值实例化——带有接收者的函数字面值 Kotlin 提供了调用带有接收者(提供接收者对象)的函数类型实例的能力。在这样的函数字面值内部,传给调用的接收者对象称为隐式的 this,以便访问接收者对象的成员而无需任何额外的限定符,亦可以使用 this 表达式访问接收者对象。 内联函数使用高阶函数会带来一些运行时的效率损失:每个函数都是一个对象,并且会捕获一个闭包:即那些在函数体内会访问到的变量。内存分配(对于函数对象和类)和虚拟调用会引入运行时间开销。 但是在许多情况下通过内联化 lambda 表达式可以消除这类的开销。我们使用 inline 修饰符标记函数,inline 修饰符影响函数本身和传递给它的lambda表达式:所有这些都将内联到调用处。 内联可能导致生成的代码增加,不过如果我们使用得当(即避免内联过大的函数),性能上会有所提升,尤其是在循环中“超多态(megamorphic)”调用处 禁用内联如果希望只内联一部分传给内联函数的 lambda 表达式参数,那么可以用 noinline 修饰符标记不希望内联的函数参数
非局部返回在Kotlin中,我们可以只使用一个正常的、非限定的 return 来退出一个命名或匿名函数。这意味着要退出一个 lambda 表达式,我们必须使用一个标签,并且在 lambda 表达式内部禁止使用裸 return ,因为 lambda 表达式不能使包含它的函数返回:
位于 lambda 表达式中,但退出包含它的函数称为非局部返回。 一些内联函数可能调用传给它们的不是直接来自函数体、而是来自另一个执行上下文的 lambda 表达式参数,例如来自局部对象或嵌套函数。在这种情况下,该 lambda 表达式中也不允许非局部控制流。为了标识这种情况,该 lambda 表达式参数需要用 crossinline 修饰符标记
具体化的类型参数有时候我们需要访问一个作为参数传给我们的一个类型,我们可以使用 reified 修饰符来限定类型参数,可以在函数内部访问,几乎就像是一个普通的类一样。 内联属性inline 修饰符可用于没有幕后字段的属性的访问器。可以标注独立的属性访问器(get或set单个方法),也可以标注整个属性,将它的两个访问器都标记为内联。在调用处,内联访问器如同内联函数一样内联 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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 10:42:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |