0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Koltin】Kotlinの`suspend`関数とは?

Posted at

Kotlinのsuspend関数とは?

〜非同期処理をシンプルに書くための魔法のキーワード〜


概要(Overview)

suspend「中断可能な関数」 を意味します。
Kotlinでは、非同期処理や長時間かかる処理を安全に実行するために、
コルーチン(Coroutine) を使いますが、suspend はそのコルーチンの“要”となるキーワードです。

suspend fun fetchUser(): User {
    delay(1000) // 一時中断(スレッドはブロックされない)
    return User("Anna")
}

この関数は delay() を呼んで1秒「中断」しますが、
スレッドはブロックされません。
そのため、同じスレッド上で他のコルーチンが並行実行できます。


なぜsuspendが必要なの?

通常の関数は、呼び出しが終わるまでスレッドを専有します。
しかし、I/O処理やネットワーク通信などは時間がかかるため、スレッドをブロックしてしまうのは非効率です。

suspend関数を使えば、
「一時中断 → 再開」という形でスレッドをブロックせずに処理を続けられるようになります。


suspend関数のポイントまとめ

項目 説明
意味 中断可能な関数
呼び出し元 他のsuspend関数、またはCoroutineScope
スレッド ブロックしない(軽量)
使用場面 ネットワーク通信、DBアクセス、I/O、長時間処理など
戻り値 普通の関数と同じ。中断可能なだけで特別ではない

使用例① — 普通の非同期処理と比較

従来のスレッド方式

fun main() {
    Thread {
        Thread.sleep(1000)
        println("Done!")
    }.start()
}

スレッドを生成し、sleepでブロック。

コルーチン方式

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000)
        println("Done!")
    }
}

delay()suspend関数なのでスレッドをブロックせず中断可能。


使用例② — suspend関数を定義して呼び出す

suspend fun fetchData(): String {
    delay(500)
    return "Data loaded"
}

fun main() = runBlocking {
    val result = fetchData()
    println(result)
}

ここでポイントは:

  • fetchDatasuspend 関数
  • runBlocking がコルーチンコンテキストを作成
  • fetchData() を安全に呼び出せる

suspend関数同士の呼び出し

suspend関数は他のsuspend関数からのみ呼び出せます。
普通の関数から呼ぶとエラーになります。

suspend fun taskA() { delay(100) }
suspend fun taskB() { taskA() } // OK

fun main() {
    taskA() // ❌ エラー: suspend関数は通常関数から呼べない
}

呼び出すには runBlockinglaunch / async などのコルーチンスコープが必要です。


suspend関数は「中断点」を持つだけの普通の関数

suspend関数は特別な戻り値型を持っているわけではありません。
ただ、コンパイラが「中断点(suspension point)」を追跡できるようにするためのマークです。

実際、suspend関数は内部的に「状態マシン」に変換されます。
つまり:

suspend fun は「中断できる可能性を持つ普通の関数」なのです。


応用:withContextを使ったスレッド切り替え

suspend関数内では、別スレッドで処理を行いたいときに withContext が使えます。

suspend fun readFile(): String = withContext(Dispatchers.IO) {
    File("data.txt").readText()
}

Dispatchers.IO はI/O処理専用のスレッドプールを使う
suspend関数内で安全にスレッドを切り替え可能


まとめ

概念 説明
suspend 中断可能な関数を定義するための修飾子
利点 スレッドをブロックせずに非同期処理を記述できる
注意点 通常関数から直接呼べない(コルーチンスコープが必要)
よく使う関数 delay(), withContext(), await(), yield() など

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?