协程只是完成处理程序周围的语法糖吗?
Are coroutines just syntactic sugar around completion handlers?
协程是否只是完成块周围的语法糖并且将在幕后创建完成块?或者协程的概念比编译器技巧更复杂和广泛得多,也就是语法糖
这不仅仅是语法糖,一点也不是。协程不阻塞线程,它们只是暂停执行,因此它们鼓励非阻塞并发编程。
协程不依赖于操作系统或 JVM 的特性(例如,它们不映射到本机线程)。相反,协程和 suspend
函数特别由编译器进行转换,生成一个 状态机 ,能够处理一般的挂起并传递挂起的协程以保持其状态。这是由 Continuations 启用的,编译器将其作为参数添加到每个挂起函数;这种技术被称为“Continuation-passing style”。
详情请看https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md
这是一篇有趣的文章,提到在他们的系统中实施 async/await:http://joeduffyblog.com/2015/11/19/asynchronous-everything/
Along with this, we added the await and async keywords. A method could be marked async:
async int Foo() { ... }
All this meant was that it was allowed to await inside of it:
async int Bar() {
int x = await Foo();
...
return x * x;
}
Originally this was merely syntactic sugar for all the callback goop above, like it is in C#. Eventually, however, we went way beyond this, in the name of performance, and added lightweight coroutines and linked stacks.
不,协程不是语法糖。您可以将协程视为可以与调用者交互的函数。当你调用一个普通函数时,比如 foo
你将控制权传递给 foo
并且必须等到 foo
完成或抛出异常。协程是可以将控制权交还给调用者的函数,调用者可以决定协程是否应该继续以及何时和如何协程应该继续。这提供了用其他语言实现特殊语言结构的机会:
- 生成器(又名
yield
关键字)类似于 C# 和 JavaScript。当用户需要迭代器的新值时,调用者继续执行协程。协程通过调用 yield()
函数返回给调用者,该函数也将一些值传递给调用者。
- Async/await 类似于 C# 和 JavaScript。当 Future(类似于 Task 或 Promise)得到解决时,调用者继续执行。协程通过调用
await()
函数返回给调用者。当 Future 被解析时,调用者将值传递给协程,并且协程由于 await()
调用而观察到该值。
- Goroutines/channels 在 Go 中。
与 C#、JavaScript 或 Go 不同,Kotlin 不以特殊语法实现这些功能中的任何一个。相反,Kotlin 仅提供 suspend fun
语法,然后您可以自己实现这些功能(或从名为 kotlinx.coroutines
的相应库中获取现有功能)。
协程是异步过程的语法糖,或者更确切地说,Actor 是可重复的异步过程。
协程是否只是完成块周围的语法糖并且将在幕后创建完成块?或者协程的概念比编译器技巧更复杂和广泛得多,也就是语法糖
这不仅仅是语法糖,一点也不是。协程不阻塞线程,它们只是暂停执行,因此它们鼓励非阻塞并发编程。
协程不依赖于操作系统或 JVM 的特性(例如,它们不映射到本机线程)。相反,协程和 suspend
函数特别由编译器进行转换,生成一个 状态机 ,能够处理一般的挂起并传递挂起的协程以保持其状态。这是由 Continuations 启用的,编译器将其作为参数添加到每个挂起函数;这种技术被称为“Continuation-passing style”。
详情请看https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md
这是一篇有趣的文章,提到在他们的系统中实施 async/await:http://joeduffyblog.com/2015/11/19/asynchronous-everything/
Along with this, we added the await and async keywords. A method could be marked async:
async int Foo() { ... }
All this meant was that it was allowed to await inside of it:
async int Bar() { int x = await Foo(); ... return x * x; }
Originally this was merely syntactic sugar for all the callback goop above, like it is in C#. Eventually, however, we went way beyond this, in the name of performance, and added lightweight coroutines and linked stacks.
不,协程不是语法糖。您可以将协程视为可以与调用者交互的函数。当你调用一个普通函数时,比如 foo
你将控制权传递给 foo
并且必须等到 foo
完成或抛出异常。协程是可以将控制权交还给调用者的函数,调用者可以决定协程是否应该继续以及何时和如何协程应该继续。这提供了用其他语言实现特殊语言结构的机会:
- 生成器(又名
yield
关键字)类似于 C# 和 JavaScript。当用户需要迭代器的新值时,调用者继续执行协程。协程通过调用yield()
函数返回给调用者,该函数也将一些值传递给调用者。 - Async/await 类似于 C# 和 JavaScript。当 Future(类似于 Task 或 Promise)得到解决时,调用者继续执行。协程通过调用
await()
函数返回给调用者。当 Future 被解析时,调用者将值传递给协程,并且协程由于await()
调用而观察到该值。 - Goroutines/channels 在 Go 中。
与 C#、JavaScript 或 Go 不同,Kotlin 不以特殊语法实现这些功能中的任何一个。相反,Kotlin 仅提供 suspend fun
语法,然后您可以自己实现这些功能(或从名为 kotlinx.coroutines
的相应库中获取现有功能)。
协程是异步过程的语法糖,或者更确切地说,Actor 是可重复的异步过程。