Kotlin语法(函数和lambda表达式)

简介:

三、函数和lambda表达式

1. 函数声明

fun double(x: Int): Int {

}

函数参数是用 Pascal 符号定义的 name:type。参数之间用逗号隔开,每个参数必须指明类型。函数参数可以有默认参数。这样相比其他语言可以减少重载。

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size() ) {
...
}

2. 命名参数

在调用函数时可以参数可以命名。这对于有很多参数或只有一个的函数来说很方便。

fun reformat(str: String, normalizeCase: Boolean = true,upperCaseFirstLetter: Boolean = true,
             divideByCamelHumps: Boolean = false,
             wordSeparator: Char = ' ') {
...
}
reformat(str,
    normalizeCase = true,
    uppercaseFirstLetter = true,
    divideByCamelHumps = false,
    wordSeparator = '_'
  )

3. 变长参数:

fun asList<T>(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts)
        result.add(t)
    return result
}

传递一个 array 的内容给函数,我们就可以使用 * 前缀操作符:

val a = array(1, 2, 3)
val list = asList(-1, 0, *a, 4)

Kotlin 中可以在文件个根级声明函数,这就意味者你不用创建一个类来持有函数。除了顶级函数,Kotlin 函数可以声明为局部的,作为成员函数或扩展函数。
Kotlin 支持局部函数,比如在另一个函数使用另一函数。局部函数可以访问外部函数的局部变量(比如闭包)。局部函数甚至可以返回到外部函数

4. 高阶函数

高阶函数就是可以接受函数作为参数并返回一个函数的函数。比如 lock() 就是一个很好的例子,它接收一个 lock 对象和一个函数,运行函数并释放 lock;

fun lock<T>(lock: Lock, body: () -> T ) : T {
    lock.lock()
    try {
        return body()
    }
    finally {
        lock.unlock()
    }
}

其实最方便的办法是传递一个字面函数(通常是 lambda 表达式):

val result = lock(lock, { sharedResource.operation() })

在 kotlin 中有一个约定,如果最后一个参数是函数,可以省略括号:

lock (lock) {
    sharedResource.operation()
}

5. 字面函数

  • 字面函数被包在大括号里
  • 参数在 -> 前面声明(参数类型可以省略)
  • 函数体在 -> 之后

字面函数或函数表达式就是一个 "匿名函数",也就是没有声明的函数,但立即作为表达式传递下去。

6. 函数类型

如:(T, T) -> Boolean
注意如果一个函数接受另一个函数做为最后一个参数,该函数文本参数可以在括号内的参数列表外的传递。

7. 函数文本语法

函数文本的完全写法是下面这样的:

val sum = {x: Int,y: Int -> x + y}

函数文本总是在大括号里包裹着,在完全语法中参数声明是在括号内,类型注解是可选的,函数体是在 -> 之后,像下面这样:

val sum: (Int, Int) -> Int = {x, y -> x+y }

8. 函数表达式

fun(x: Int, y: Int ): Int = x + y

9. 内联函数

在高阶函数前增加inline注解可以指定函数內联。inline 标记即影响函数本身也影响传递进来的 lambda 函数:所有的这些都将被关联到调用点。
内联可能会引起生成代码增长,所以可以使用noinline来指定某些函数不进行內联。

注意有些内联函数可以调用传递进来的 lambda 函数,但不是在函数体,而是在另一个执行的上下文中,比如局部对象或者一个嵌套函数。在这样的情形中,非局部的控制流也不允许在lambda 函数中。为了表明,lambda 参数需要有 InlineOptions.ONLY_LOCAL_RETURN 注解

参考:

  1. http://kotlinlang.org/docs/reference/basic-syntax.html
  2. http://huanglizhuo.gitbooks.io/kotlin-in-chinese
本文转自天天_byconan博客园博客,原文链接:http://www.cnblogs.com/tiantianbyconan/p/4801720.html ,如需转载请自行联系原作者
相关文章
|
30天前
|
安全 Kotlin
Kotlin教程笔记(23) -作用域函数
Kotlin教程笔记(23) -作用域函数
91 6
|
30天前
|
Kotlin
Kotlin教程笔记(21) -高阶函数与函数引用
Kotlin教程笔记(21) -高阶函数与函数引用
39 6
|
2月前
|
IDE 开发工具 Kotlin
Kotlin - 函数与Lambda表达式
Kotlin - 函数与Lambda表达式
44 13
|
2月前
|
IDE 开发工具 Kotlin
Kotlin教程笔记(6) - 函数与Lambda表达式
Kotlin教程笔记(6) - 函数与Lambda表达式
55 1
|
Kotlin
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(二)
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(二)
130 0
|
Kotlin
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(一)
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(一)
292 0
|
3月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
42 1
|
4月前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
119 1
|
6月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
184 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
5月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
67 4