未使用戻り値チェッカー
この機能は、将来のKotlinリリースで安定化および改善される予定です。 フィードバックは、課題トラッカー YouTrack までお寄せください。
詳細については、関連する KEEP提案 を参照してください。
未使用戻り値チェッカーを使用すると、無視された結果(ignored results)を検出できます。 これらは、Unit、Nothing、または Nothing? 以外を返す式から得られた値のうち、以下のいずれにも該当しないものを指します:
- 変数やプロパティに格納されている。
- 返り値として返されている、またはスローされている。
- 別の関数の引数として渡されている。
- 呼び出しまたはセーフコールのレシーバとして使用されている。
if、when、whileなどの条件式でチェックされている。- ラムダの最後の文として使用されている。
このチェッカーは、++ や -- などのインクリメント・デクリメント操作や、右辺で現在の関数を抜けるような論理演算のショートカット(例:condition || return)については、無視された結果として報告しません。
未使用戻り値チェッカーを使用することで、関数呼び出しが意味のある結果を生成しているにもかかわらず、その結果が暗黙的に破棄されているバグを特定できます。これにより、予期しない動作を防ぎ、そのような問題の追跡を容易にすることができます。
以下は、文字列が作成されたものの使用されていないため、チェッカーが無視された結果として報告する例です:
fun formatGreeting(name: String): String {
if (name.isBlank()) return "Hello, anonymous user!"
if (!name.contains(' ')) {
// チェッカーはこの結果が無視されているという警告を報告します:
// "Unused return value of 'plus'."
"Hello, " + name.replaceFirstChar(Char::titlecase) + "!"
}
val (first, last) = name.split(' ')
return "Hello, $first! Or should I call you Dr. $last?"
}未使用戻り値チェッカーの設定
コンパイラが無視された結果をどのように報告するかは、-Xreturn-value-checker コンパイラオプションで制御できます。
以下のモードがあります:
disable: 未使用戻り値チェッカーを無効にします(デフォルト)。check: チェッカーを有効にし、マークされた関数からの無視された結果に対して警告を報告します。full: チェッカーを有効にし、プロジェクト内のすべての関数をマーク済みとして扱い、無視された結果に対して警告を報告します。
すべてのマークされた関数はその性質が伝播され、あなたのコードを依存関係として使用するプロジェクトでチェッカーが有効になっている場合、無視された結果が報告されます。
プロジェクトで未使用戻り値チェッカーを使用するには、ビルド設定ファイルにコンパイラオプションを追加します:
// build.gradle(.kts)
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xreturn-value-checker=check")
}
}<!-- pom.xml -->
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
..
<configuration>
<args>
<arg>-Xreturn-value-checker=check</arg>
</args>
</configuration>
</plugin>無視された結果をチェックする関数をマークする
-Xreturn-value-checker コンパイラオプションを check に設定すると、チェッカーは、Kotlin標準ライブラリのほとんどの関数のよう、マークされている式からの無視された結果のみを報告します。
自身のコードをマークするには、@MustUseReturnValues アノテーションを使用します。チェッカーの対象にしたいスコープに応じて、ファイル、クラス、または関数に適用できます。
例えば、ファイル全体をマークできます:
// このファイル内のすべての関数とクラスをマークし、チェッカーが未使用の戻り値を報告するようにします
@file:MustUseReturnValues
package my.project
fun someFunction(): Stringまたは、特定のクラスをマークします:
// このクラス内のすべての関数をマークし、チェッカーが未使用の戻り値を報告するようにします
@MustUseReturnValues
class Greeter {
fun greet(name: String): String = "Hello, $name"
}
fun someFunction(): Int = ...
-Xreturn-value-checkerコンパイラオプションをfullに設定することで、プロジェクト全体にチェッカーを適用できます。このオプションを使用する場合、コードに@MustUseReturnValuesをアノテートする必要はありません。
無視された結果の報告を抑制する
特定の関数に対して報告を抑制するには、@IgnorableReturnValue をアノテートします。MutableList.add のように、結果を無視することが一般的で想定内である関数にアノテートしてください:
@IgnorableReturnValue
fun <T> MutableList<T>.addAndIgnoreResult(element: T): Boolean {
return add(element)
}関数自体にアノテートせずに警告を抑制することもできます。これを行うには、アンダースコア構文(_)を使用して、結果を特別な名前のない変数に代入します:
// 無視できない関数
fun computeValue(): Int = 42
fun main() {
// 警告を報告:結果が無視されています
computeValue()
// 特別な未使用変数を使用して、この呼び出し箇所でのみ警告を抑制します
val _ = computeValue()
}関数のオーバーライドにおける無視された結果
関数をオーバーライドすると、そのオーバーライドはベース宣言のアノテーションによって定義された報告ルールを継承します。これは、ベース宣言がKotlin標準ライブラリや他のライブラリ依存関係の一部である場合にも適用されるため、Any.hashCode() などの関数のオーバーライドに対しても、チェッカーは無視された結果を報告します。
また、@IgnorableReturnValue が付いた関数を、戻り値の使用を要求する別の関数でオーバーライドすることはできません。ただし、@MustUseReturnValues がアノテートされたクラスやインターフェースにおいて、その結果を安全に無視できる場合には、オーバーライドに @IgnorableReturnValue をマークすることができます:
@MustUseReturnValues
interface Greeter {
fun greet(name: String): String
}
object SilentGreeter : Greeter {
@IgnorableReturnValue
override fun greet(name: String): String = ""
}
fun check(g: Greeter) {
// 警告を報告:未使用の戻り値
g.greet("John")
// 警告なし
SilentGreeter.greet("John")
}Javaアノテーションとの相互運用性
一部のJavaライブラリでは、異なるアノテーションを使用して同様のメカニズムを採用しています。未使用戻り値チェッカーは、以下のアノテーションを @MustUseReturnValues を使用するのと同等として扱います:
com.google.errorprone.annotations.CheckReturnValueedu.umd.cs.findbugs.annotations.CheckReturnValueorg.jetbrains.annotations.CheckReturnValueorg.springframework.lang.CheckReturnValueorg.jooq.CheckReturnValue
また、com.google.errorprone.annotations.CanIgnoreReturnValue を @IgnorableReturnValue を使用するのと同等として扱います。
