Kotlinのスコープ関数の戻り値の違いと使い分けを初心者向けに解説!
生徒
「Kotlinのスコープ関数っていろいろありますけど、何がどう違うんですか?特に戻り値の違いがよくわかりません…」
先生
「たしかにlet・run・apply・also・withは似ているようで、実は戻り値が違うんですよ。そこをしっかり理解すれば、使い分けもスムーズになりますよ!」
生徒
「なるほど…!戻り値で使い方が変わるってことですか?」
先生
「そのとおり!今回は初心者でもわかるように、それぞれの違いや使い方をゆっくり解説していきますね!」
1. スコープ関数とは?初心者が知っておくべき基本
Kotlinの「スコープ関数(Scope Functions)」とは、特定のオブジェクトに対して「一時的なスコープ(範囲)」を作り、その中でコードを実行するための便利な仕組みです。これを使うことで、変数名を何度も書かずに処理をまとめられるため、コードがスッキリと読みやすくなります。
例えば、「ペン(オブジェクト)」を手に取って、そのペンで「名前を書き(処理1)」、「キャップを閉める(処理2)」という一連の動作を、ひとまとめのグループとして記述できるイメージです。プログラミング未経験の方でも、まずは「特定のモノ(オブジェクト)に集中して、いくつかの作業をまとめて行うための魔法の合図」だと考えてみてください。
代表的な5つのスコープ関数
- let(レット)
- run(ラン)
- apply(アプライ)
- also(オールソー)
- with(ウィズ)
これらは非常によく似ていますが、主な違いは「作業のあとで何が返ってくるか(戻り値)」と「オブジェクトをどう呼ぶか」の2点だけです。まずは、実際のシンプルなコードで雰囲気をつかんでみましょう。
fun main() {
// 1. 普通に書く場合(名前を何度も書く必要がある)
val name = "kotlin"
println(name.uppercase())
println(name.length)
// 2. スコープ関数(let)を使う場合(スッキリまとまる!)
"kotlin".let {
println(it.uppercase())
println(it.length)
}
}
このように、スコープ関数を使うと「it」などのキーワードを使って、対象のオブジェクトをスマートに操作できます。それでは、次の章から最も重要な「戻り値の違い」について詳しく解説していきます!
2. スコープ関数の戻り値の違いとは?使い分けの極意
Kotlinのスコープ関数を使いこなす最大のカギは、処理が終わった後に何が手元に残るか、つまり「戻り値」の違いを理解することです。戻り値には大きく分けて2つのパターンがあります。
① 最後に計算した結果を返す
let, run, with が該当します。データの変換や、計算結果を別の変数に代入したい時に便利です。
② 操作したオブジェクト自身を返す
apply, also が該当します。設定変更やログ出力後も、そのまま同じオブジェクトを使い続けたい(メソッドチェーン)時に最適です。
プログラミング未経験の方でもイメージしやすいよう、具体的なサンプルコードで比較してみましょう。例えば「お弁当の価格を計算する」場合と「お弁当に具材を追加する」場合では、選ぶべき関数が変わります。
fun main() {
// 1. 「計算結果」を返すパターン (let)
val priceWithTax = 500.let {
it * 1.1 // 最後に計算した「550.0」が戻り値になる
}
println("税込価格は ${priceWithTax}円 です")
// 2. 「自分自身」を返すパターン (apply)
val lunchBox = mutableListOf("お米").apply {
this.add("焼き鮭") // 自分自身(リスト)に具材を追加
this.add("卵焼き") // 戻り値は追加後の「リストそのもの」
}
println("お弁当の中身: $lunchBox")
}
このように、「加工した後の"値"が欲しいのか」それとも「加工した"物"そのものが引き続き欲しいのか」という視点を持つと、驚くほどスムーズにコードが書けるようになります。それでは、具体的にそれぞれの関数がどのようなシーンで活躍するのか、詳しく見ていきましょう!
3. letの戻り値と使い方:データを加工して受け取る
Kotlinのスコープ関数の中でも、letは「手元にあるデータを加工して、その結果を別の変数に保存したい」という場面で最もよく使われます。プログラミング初心者の方なら、「一時的な作業机でデータを編集し、完成品を外に出す」イメージを持つと分かりやすいでしょう。
letの最大の特徴は、ラムダ式({ }の中)の最後に書いたコードの結果が、そのまま戻り値として返ってくる点にあります。これにより、元のデータを汚さずに新しい形へ変換して受け取ることが可能です。
// 1. 元のデータを用意
val originalText = "kotlin"
// 2. letを使って加工(itはoriginalTextを指す)
val result = originalText.let {
// ここで加工処理を行う
it.uppercase() // 全て大文字に変換
}
// 3. 加工後の結果を表示
println(result)
KOTLIN
上記のサンプルでは、小文字の「kotlin」をuppercase()で大文字に変換し、その結果を変数resultに代入しています。もしletを使わない場合、何度も同じ変数名を書く必要がありますが、letを使えば処理をスッキリとひとまとめに記述できます。
このように、letは「元の値を元に、新しい形に変換した結果(戻り値)を取り出す」ときに非常に便利なツールです。特に、変数の中身が空(null)でないかチェックした後に処理を続けたい場合など、安全にプログラムを動かすためにも多用されます。
4. runの戻り値と使い方:オブジェクト操作をスッキリさせる
runスコープ関数は、letと同じように「ブロックの最後に書いた式の結果」を戻り値として返します。最大の特徴は、ブロック内で対象のオブジェクトを「this」として扱える点にあります。
プログラミング初心者の方には、「そのオブジェクト自身になりきって、中の機能(メソッド)を直接呼び出せる魔法の箱」だとイメージすると分かりやすいでしょう。
fun main() {
// 文字列に対してrunを使い、その結果を受け取る
val result = "hello-kotlin".run {
// thisは "hello-kotlin" を指す
// thisを省略して、直接toUpperCase()などの機能を呼べる
val upper = this.uppercase()
val reversed = upper.reversed()
// 最後に書いたこの値が、resultに代入される
"変換結果は:$reversed"
}
println(result)
}
変換結果は:NILTOK-OLLEH
上記のサンプルでは、元の文字列を大文字にして反転させた結果を、最後にresultという変数に返しています。itを使うletとは違い、thisを使うrunは「オブジェクトのプロパティやメソッドを連続して操作したい時」に非常に便利です。
例えば、スマートフォンの設定アプリなどで「名前をセットし、色を変え、最後に保存ボタンを押す」といった一連の動作を、一つのまとまりとして読みやすく記述できるのがrunの強みです。
5. applyの戻り値と使い方:オブジェクトの初期化をスマートに
Kotlinのスコープ関数の中でも、特に「オブジェクトの生成と設定」をセットで行う際に重宝するのがapplyです。最大の特徴は、「ブロック内での処理が終わったあと、自分自身(呼び出し元オブジェクト)を返す」という点にあります。
プログラミング未経験の方でもイメージしやすいように、お弁当箱(StringBuilder)を準備して、その中身を詰める作業を例に見てみましょう。
// applyを使って、StringBuilderの作成と文字の追加を一度に行う
val message = StringBuilder().apply {
// この中では「自分自身」に対して操作ができる
append("こんにちは!")
append("Kotlinの世界へようこそ。")
append("applyを使えばコードがスッキリします。")
}
// 最終的に設定が完了したmessage(StringBuilder)がそのまま返ってくる
println(message.toString())
こんにちは!Kotlinの世界へようこそ。applyを使えばコードがスッキリします。
通常、オブジェクトを作ってから値をセットする場合、何度も変数名を打ち込む必要があります。しかし、applyを使えば、thisを省略して直接プロパティやメソッドにアクセスできるため、コードの可読性が飛躍的に向上します。特にAndroidアプリ開発などのUI構築において、ボタンのテキストや色をまとめて設定するシーンで非常によく使われる、必須のテクニックです。
6. alsoの戻り値と使い方:処理を「ついでに」実行する
also(オールソー)は、直訳すると「~もまた」という意味です。その名の通り、「メインの処理に加えて、ついでにこの処理もやっておきたい」という場面で非常に重宝するスコープ関数です。
最大の特徴は、applyと同じく「操作した後のオブジェクトそのもの」が戻り値として返ってくる点です。しかし、ブロック内でのオブジェクトの扱い方はletと同じようにit(または任意の名前)を使って参照します。
「データを作成した直後に、ついでにログを出力したい」とか「デバッグのために中身を確認したい」といった、元のデータを汚さずにちょっとした脇道の処理を挟みたいときに最適です。
// 1. リストを作成し、その流れで項目を追加する
val list = mutableListOf("リンゴ", "バナナ").also {
// itは「作成したリスト自身」を指します
it.add("オレンジ")
println("【ログ】リストに要素を追加しました:$it")
}
// 最終的に変数listには、操作後のリストがそのまま入ります
println("最終結果: $list")
【ログ】リストに要素を追加しました:[リンゴ, バナナ, オレンジ]
最終結果: [リンゴ, バナナ, オレンジ]
プログラミング未経験の方にとって混乱しやすいのが「applyとの違い」ですが、alsoはitを使うため、「今どのオブジェクトを操作しているのか」が明示的になり、読み間違い(バグ)を防ぎやすいというメリットがあります。特に行数が少し長くなるような付随処理を書く場合は、このalsoを使うのが現場のベストプラクティスです。
7. withの戻り値と使い方
withは少し特殊で、対象のオブジェクトを引数にして、ブロック内はthisで操作します。戻り値は最後の式の結果です。
val length = with("Kotlin") {
println("文字数は${length}です")
length
}
println(length)
文字数は6です
6
withは「特定のオブジェクトに対して複数の処理をしたいとき」に使います。
Kotlinを基礎からしっかり学びたい人や、 Java経験を活かしてモダンな言語にステップアップしたい人には、 定番の入門書がこちらです。
基礎からわかるKotlinをAmazonで見る※ Amazon広告リンク
8. 戻り値で使い分けるコツ
ここまでのポイントをおさらいしましょう。Kotlinのスコープ関数の使い分けは、「何を返したいか」が大きなポイントです。
letやrun:処理の結果を返したいときapplyやalso:元のオブジェクトを返したいときwith:少し特殊だが、処理の結果を返す
たとえば、何かを加工した結果を使いたいならletやrun、オブジェクトの初期設定をしたいならapplyやalsoが合っています。
【未経験OK】Kotlinで始めるプログラミング入門|ゼロから「動く喜び」を体験する60分
「プログラミングを始めたい」を形にする。最新言語Kotlinで楽しむ、ものづくりの第一歩。
本講座は、プログラミング経験が全くない方のためのエントリー講座です。「コードを書くってどういうこと?」という基本から、世界中で使われている最新言語Kotlin(コトリン)を使って、実際にプログラムを動かすまでを体験します。難しい理屈よりも、まずは「自分の手で動かす楽しさ」を最短距離で実感していただきます。
具体的な体験内容と環境
【つくるもの】
簡単な言葉を入力すると自動で返答してくれる「対話型ミニプログラム」や、計算を自動化する「便利ツール」をゼロから作成します。黒い画面に自分の書いた文字が表示される瞬間は、最高の感動体験です。
【開発環境】
プロのエンジニアが実際に使っている開発ツールIntelliJ IDEA(インテリジェイ)をインストールします。ボタン一つで日本語化し、初心者でも迷わず操作できる「魔法の設定」を一緒に行います。
この60分で得られる3つの体験
プロと同じ道具を揃えることで、明日から一人でもプログラミングを続けられる環境が整います。
「変数」や「型」といった難しい言葉も、身近な例え話で解説。モヤモヤをゼロにします。
Kotlinは英語に近くて読みやすいのが特徴。自分でコードを読んで、間違いを見つけるコツも伝授します。
※本講座は、パソコン操作が不安な方でも安心して受講いただける完全マンツーマンです。あなたのペースに合わせて、一つずつ丁寧に進めていきます。
Kotlinで始めるプログラミング入門|ゼロから「動く喜び」を体験