1234567891011121314151617181920212223242526272829303132333435363738 |
- +++
- +++
-
- == Kotlin
-
- https://kotlinlang.org/[Kotlin] is a modern language that can run on
- the JVM (as well as compiling to JavaScript or to native binaries).
- I use Kotlin for any Android app I write, and most desktop apps that
- require a GUI.
-
- === Assorted coroutine notes
-
- * *launched* in the context of a scope, e.g. `GlobalScope`
- * `launch` and `runBlocking` are both builders
- ** Can parameterise `runBlocking` for e.g. tests - `runBlocking<Unit> {...}`
- ** Builders return a job, can call `job.join()` to wait, `job.cancel()` to stop
- ** Every builder adds a `CoroutineScope` to the scope of a code block
- ** `launch`/`runBlocking` operate on current scope
- * `coroutineScope` is a builder to manually create a scope
- * `suspend` functions don't carry the scope
- ** keep a reference in the class/fun
- ** make them an extension method on CoroutineScope
- * Coroutines launched in `GlobalScope` don't keep the process alive if `main()` returns
- * Cancellation is co-operative - must throw `CancellationException`
- ** Can check `isAlive` property
- ** `withContext(NonCancellable)` if job *can't* be cancelled (e.g. suspend fun in a finally block)
- * `withTimeout` and `withTimeoutOrNull` cancel automatically
- * Children can be cancelled with `coroutineContext.cancelChildren()`
- * `async` is like `launch` but returns a `Deferred`
- * Contexts are job + dispatcher
- * Dispatcher specifies thread to run on
- * Launchers take an optional context
- ** `launch(newSingleThreadContext("name")) {...}`
- * `GlobalScope`'s dispatcher uses a shared threadpool
- * Can get own job from `CoroutineContext[Job]`
- * `CoroutineName` gives named context
- ** Can concat contexts with `+`
- * `select` can receive data from multiple channels, like Go
|