スコープ関数の使い分けどうする?
今までスコープ関数をなんとなく使っていた人向けに(自戒)、ざっくりとした使い分けのまとめをお届けします。
まず、前提としてはっきりとした使い分けはないと思っています。
だからこそ、「ざっくりと」とタイトルに明記しました。
個人的に使い分けの意義としては、可読性にあると思います。
結局、スコープ関数のそれぞれはオブジェクトの操作方法が違うだけで、そんなに大きく違うわけではない所感です。
それでは、それぞれの用途を可読性という観点とともに見ていきましょう。
let
特定のオブジェクトの操作をする前にnullチェックを入れたい場合に使いどころがあります。
これによって、短いコードでnullチェックとオブジェクトの操作を表現することが出来ます。
サンプルコード
val textView: TextView? = null
textView?.let {
it.text = "non-null"
it.setTextColor(ContextCompat.getColor(this, R.color.black))
}
letで行っていることを具体的に表現すると、この場合だと少し行数が長くなってしまいますね。
val textView: TextView? = null
if(textView != null) {
textView.text = "non-null"
textView.setTextColor(ContextCompat.getColor(this, R.color.black)
} else {
return
}
with
withは、non-nullなオブジェクトの操作をする際に使いどころがあります。
このスコープ内は、textViewオブジェクトの操作しているのだなと読んでいる人に伝えられます。
サンプルコード
val textView = TextView()
with(textView) {
text = "hello world"
size = 12.sp
color = R.color.hoge
}
withを使用しないと、同じオブジェクトを指定するので少し冗長的に見えます。
val textView = TextView()
textView.text = "hello world"
textView.size = 12.sp
textView.color = R. color.hoge
run
runはnullチェックとオブジェクト操作を同時に行います。
余談ですが自分自身、名前のカッコよさから個人開発は、全部runを使ってました。
サンプルコード
val textView: TextView? = null
textView?.run {
text = "hello world"
size = 12.sp
color = R.color.hoge
}
runを使わないで書くと、このようになります。
val textView: TextView? = null
if(textView != null) {
textView.text = "non-null"
textView.size = 12.sp
textView.color = R.color.hoge
} else {
return
}
apply
レシーバーオブジェクトは返したいけども、操作自体はついでにやるものの戻り値とは切り離したい時に使います。
これにより、ComposeViewを返しつつ、オブジェクトの操作も行っているというのが伝わります。
サンプルコード
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
HogeScreen()
}
return後の処理は走らないので、applyなしで同じことをやろうとしてもKotlinの言語仕様的に難しいかと思います。
参考