今週は第55回を開催しました!
引き続きKotlin Hands-onをすすめています。
前回の様子はコチラ↓
[第55回の様子]
2021/3/10に第55回を開催した。
参加メンバーは自分をいれて4名。メンバーは最近固定気味。
今回も自分はナビゲータ役を担当した。
勉強会本編の内容としては、ひき続きIntroduction to Coroutines and Channelsハンズオンを進めた。第5章 Concurrencyのタスク部分を実施して、あと少し残して終わり。
全体としては第9章まであるので、ようやく後半戦という感じ。
[学んだことや疑問点]
- Introduction to Coroutines and Channels: 5. Concurrency
 - 今回のタスクは
loadContributorsConcurrent()を実装せよというもの 
suspend fun loadContributorsConcurrent(
    service: GitHubService, req: RequestData
): List<User> = coroutineScope {
     // この部分を実装するのが課題
}
coroutineScope()を使うと新しいスコープを定義できるらしい- スコープの使い道がいまいち理解できないまま問題を解いてみる
 - 方針としては以下のように
Deferredのリストを受け取って、awaitAll()すればよい - 前回も不思議だったのだけれど、
Listに新しくawaitAll()関数が生えるのが面白い 
val deferreds: List<Deferred<List<User>>> = repos.map { repo ->
    async {
        // load contributors for each repo
    }
}
deferreds.awaitAll() // List<List<User>>
- 前々回の
loadContributorsSuspend()の実装を参考にすべし、ということで最初に出た解答がこちら 
val repos = service
    .getOrgRepos(req.org)
    .also { logRepos(req, it) }
    .body() ?: listOf()
// ここまではloadContributorsSuspendそのまま利用
val deferreds: List<Deferred<List<User>>> = repos.map { repo ->
    async {
        service
            .getRepoContributors(req.org, repo.name)
            .also { logUsers(repo, it) }
            .bodyList()
    }
}
deferreds.awaitAll().flatten() // List<List<User>>をList<User>に変換
[まとめ]
モブプログラミング・スタイルで、Introduction to Coroutines and Channelsハンズオンを進めた。
coroutineScope()という新しい概念が出てきたけどあまり説明がなかった。たぶんマルチスレッドでいうスレッドを分ける的な話だとは思うけど……。詳細は次回以降に期待。
今週のプルリクエストはこちら。