Kotlin入坑(六)函数

来源:互联网 发布:知乎神回复2016 知乎 编辑:程序博客网 时间:2024/06/08 12:33

函数声明 使用 fun 关键字 参数使用 name: type 的形式表示 左边是参数的名字 右边是参数的类型,最后的冒号后面代表返回值的类型。如果这个函数没有返回值可以省略或者使用Unit 代替

fun double(x: Int): Int {    return 2 * x}

参数可以有默认值 比如上面的( x : Int = 0)
用法:

val result = double(2)

当函数返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可:

fun double(x: Int): Int = x * 2

可变数量的参数(Varargs

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

允许将可变数量的参数传递给函数:

val list = asList(1, 2, 3)

函数作用域
在 Kotlin 中函数可以在文件顶层声明,这意味着你不需要像一些语言如 Java、C# 或 Scala 那样创建一个类来保存一个函数。此外除了顶层函数,Kotlin 中函数也可以声明在局部作用域、作为成员函数以及扩展函数。

Kotlin 支持局部函数,即一个函数在另一个函数内部

fun dfs(graph: Graph) {    fun dfs(current: Vertex, visited: Set<Vertex>) {        if (!visited.add(current)) return        for (v in current.neighbors)            dfs(v, visited)    }    dfs(graph.vertices[0], HashSet())}

局部函数可以访问外部函数(即闭包)的局部变量,所以在上例中,visited 可以是局部变量:

fun dfs(graph: Graph) {    val visited = HashSet<Vertex>()    fun dfs(current: Vertex) {        if (!visited.add(current)) return        for (v in current.neighbors)            dfs(v)    }    dfs(graph.vertices[0])}

泛型函数 函数可以有泛型参数,通过在函数名前使用尖括号指定:

fun <T> singletonList(item: T): List<T> {    // ……}

高阶函数

高阶函数是将函数用作参数或返回值的函数
Lambda 表达式

  • lambda 表达式总是被大括号括着
  • 其参数(如果有的话)在 -> 之前声明(参数类型可以省略)
  • 函数体(如果存在的话)在 -> 后面

高阶函数的另一个例子是 list中的map()方法

fun <T, R> List<T>.map(transform: (T) -> R): List<R> {    val result = arrayListOf<R>()    for (item in this)        result.add(transform(item))    return result}

例子:

val ints = listOf<Int>(1,2,3,4,5,5)//可以如下调用val resmap = ints.map {               value -> value * 2               }Log.i("resmap",resmap.toString());//结果12-18 13:54:32.147 9639-9639/com.chs.kotlintext I/resmap: [2, 4, 6, 8, 10, 10]

另一个有用的约定是,如果函数字面值只有一个参数, 那么它的声明可以省略(连同 ->),其名称是 it
所以上面的例子可以写成

val resmap = ints.map {            it * 2        }//返回值和上面一样12-18 14:00:13.812 10038-10038/com.chs.kotlintext I/resmap: [2, 4, 6, 8, 10, 10]

内联函数

使用 inline 关键字
内联目前主要是应用在 函数参数是lambda表达式的代码中,可以提高高阶函数的效率

inline fun <T> lock(lock: Lock, body: () -> T): T {    // ……}

inline修饰符影响函数本身和传给它的 lambda 表达式:所有这些都将内联到调用处。如果有两个以上的lambda参数,只想联一个怎么办,就用到了 noinline 关键字

inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {    // ……}

协程

在 Kotlin 1.1+ 中协程是实验性的

关于协程的内容很多

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

简单例子

项目build.gradle文件中加入下面引用

compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.20'

launch 在不阻塞当前线程的情况下启动新协程,并将协程的引用作为Job返回。当作业被取消时,协程被取消。

launch { // 在后台启动新的协程并继续            delay(1000L) // 非阻塞延迟1秒(默认时间单位是ms)            Log.i("launch","World") // 延迟后打印        }        Log.i("launch","Hello") // 主线程在协程延迟的时候继续

打印结果:

12-18 16:52:25.827 17383-17383/com.chs.kotlintext I/launch: Hello12-18 16:52:26.831 17383-17428/com.chs.kotlintext I/launch: World
原创粉丝点击