Kotlin编程风格与协程入门

2018-11-14  本文已影响14人  程序引力
欢迎关注程序引力

笔者近日有幸参与到与Kotlin核心作者Hadi Hariri的研讨会。Hariri先生作为JetBrains开发者推广团队的领导,在研讨会中分享了Kotlin的若干编程风格,以及协程与并发编程的内容。其中分享的知识与经验均来自于Hariri先生。

前言

2017年Google宣布Kotlin在Android开发上正式受到官方支持,使得更多的Android开发者迁移到Kotlin。截止到2018年冬,Kotlin 1.3 已经发布,也带来了许多新特性。本文将会以4种编程风格作为背景,引出Kotlin中有关协程特性的介绍。

编程风格

不管对于怎样的程序语言,开发者在使用过程中会形成各种各样的编程风格(Programming Style),或者对于一些新型语言,在设计之初就会参考这些风格。

对于异步编程的场景,主要有4类风格:

1. 异步线程

在实践中,最普通的方式就是在需要并发编程的场景中,手动创建线程,然后启动线程,这也是最为基础也是最为原始的方式。但是它也有着一些缺点:

2. 回调函数

回调函数是一种常用的异步编程风格,将函数或者持有函数的对象作为参数传递给函数,然后在其执行完毕后,调用回调函数。但是,回调函数也有着一些缺点,例如对于Javascript的一个毁掉函数的例子:

fs.readdir(source, function (err, files) {
  if (err) {
    console.log('Error finding files: ' + err)
  } else {
    files.forEach(function (filename, fileIndex) {
      gm(source + filename).size(function (err, values) {
        if (err) {
          console.log('Error identifying file size: ' + err)
        } else {
          aspect = (values.width / values.height)
          widths.forEach(function (width, widthIndex) {
            height = Math.round(width / aspect)
            this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
              if (err) console.log('Error writing file: ' + err)
            })
          }.bind(this))
        }
      })
    })
  }
})

从代码中可以看出,回调函数中可能传入另一个回调函数,依次嵌套许多层,这会让代码难以阅读和维护。这也被称为“回调地狱”(callback hell).

同时,在这样的嵌套的回调中,如果发生异常,很难去处理异常,这也是另一个缺点。

3. Future/Promise/Rx风格

这种风格表示通过定义一个接口,然后返回这个接口,再一次调用这个接口中的方法来完成任务的一种编程风格。另外,如Rx系列支持的链式调用也是属于这一种风格。以RxJava的调用方式为例:

Observable.create()
.observeOn()
.subscribOn()
.subscrib()

该例子省略了许多参数。但从该例子中也看得出来,该编程风格与回调函数的不同是将嵌套的多个方法,变成‘链式’调用了。
该方法虽然没有了‘回调地狱’的问题,但是其返回值不是真正执行业务的方法的返回值,而是一个接口。为此,引出了下一种编程风格。

4.Kotlin 协程

对于Kotlin协程,需要先使用关键字suspend声明可挂起函数:

suspend fun doSomething(foo: Foo): Bar { ... }
suspend fun doSomethingElse(foo: Foo): Bar { ... }

为此,在使用launch方法,既可以启动协程

launch {
    val bar = doSomething(foo())
    val bar2 = doSomethingElse(foo())
}

上面两个方法经过编译处理后,会运行在异步的协程中。

上一篇下一篇

猜你喜欢

热点阅读