Jetpack Composeでコード書いていると、次のような警告を見かけることがあります。
Modifier parameter should be the first optional parameter
Modifierは最初のデフォルト引数であるべき、という話ですね。
例えば次のようなコードを書いた場合に上記の警告が出ます。
@Composable
fun SampleComposable(
param: Boolean,
optionalParam: String = "First optional param",
modifier: Modifier = Modifier,
)
そしてこの方針はModifierのドキュメントにも書かれています。
It should appear as the first optional parameter in the parameter list; after all required parameters (except for trailing lambda parameters) but before any other parameters with default values.
しかし何故Modifierは最初のデフォルト引数でないといけないのでしょうか?
先に結論
- ガイドライン上、そう定められているため
- APIの一貫性を保つため
詳細
警告を出しているLintの実装は以下です。
このコミットログを追うと "for consistency with Compose guidelines" という記述が確認できます。
https://android-review.googlesource.com/c/platform/frameworks/support/+/1502816
そしてComposeのAPIガイドラインには次のような記述があります。
Modifiers occupy the first optional parameter slot to set a consistent expectation for developers that they can always provide a modifier as the final positional parameter to an element call for any given element's common case.
Modifierを常に最初のデフォルト引数にしていくおくと、開発者は最後にmodifierを書けばいいと期待してコードを書けるらしいです。どういうことでしょう?
例えば、Text
やButton
が次のように実装されていたとします。
fun Text(
text: String,
modifier: Modifier = Modifier, // 1st optional parameter
color: Color = Color.Unspecified
)
@Composable
fun Button(
onClick: () -> Unit,
enabled: Boolean = true,
modifier: Modifier = Modifier, // 2nd optional parameter
)
これらをModifierを指定して呼び出すと次のようになります。
Text("sample text", Modifier.padding(8.dp))
Button({ /* onClick */ }, modifier = Modifier.padding(8.dp))
Text
がシンプルに書けた一方、Button
のModifierは2番目のデフォルト引数であるため、modifier=
の名前付き引数にする必要が出てしまいました。
このようにModifier引数の順番が不規則であると、Composable毎に引数の順番を意識して書く必要が出てしまいます。Modifierが各所で使われる仕組みであることを考えると、これは良くないでしょう。
従って、一貫性を保つためにModifierは最初のデフォルト引数であるべき、としているわけです。
これを守ることでComposableを書くときには必須のパラメータを記述して、最後にModifierを書けばいい、という共通認識でコードが書くことができます。