LoginSignup
2
0

More than 1 year has passed since last update.

var count by remember { mutableStateOf(0) } の意味

Last updated at Posted at 2021-09-12

この記法の意味と、以下のような import 文を記述しなければならない理由がわからなかったので、これらの意味を調べていく。

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

var ... by ... とは

委譲プロパティと呼ばれるもの。この構文を使うためには、Foo クラスに getValue(Nothing?, KProperty<*>): TsetValue(Nothing?, KProperty<*>, value: T) を実装する必要がある。

import kotlin.reflect.KProperty

class Foo {
  operator fun getValue(a: Nothing?, b: KProperty<*>): Int {
    return 1
  }
  operator fun setValue(a: Nothing?, b: KProperty<*>, value: Int) {
  }
}

fun main() {
  var foo by Foo()
  println(foo)  //=> 1
  foo = 2
  println(foo)  //=> 1
}

foo は Int 型にも関わらず、式評価時と代入時には getValue()setValue() が実行される。プロパティに似ている。

まとめると、次のような構造をしていることがわかる。

var foo/* 変数名 */ by Foo()/* getValueとsetValueを持つオブジェクト */

var count by remember { mutableStateOf(0) } とは

これを var count by remember { mutableStateOf(0) } に当てはめる。

  • count : 変数名
  • remember { mutableStateOf(0) } : getValuesetValueを持つオブジェクト

remember { mutableStateOf(0) }MutableState<Int> 型のインスタンスを返す関数の呼び出しである。MutableState<Int> とそのインタフェースである State<T> はそれぞれ次のように定義されている。

package androidx.compose.runtime

@Stable
interface State<out T> {
    val value: T
}

@Stable
interface MutableState<T> : State<T> {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

var count by remember { ... } といった記述を行うために必要な getValuesetValue の定義が見当たらない。これらのメソッドは拡張関数として定義されている。

package androidx.compose.runtime

@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> State<T>.getValue(thisObj: Any?, property: KProperty<*>): T = value

@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> MutableState<T>.setValue(thisObj: Any?, property: KProperty<*>, value: T) {
    this.value = value
}

よって、var count by remember { ... } と書くためには次の import 文を追加する必要がある。

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

まとめ

  • var A by B という記法は委譲プロパティと呼ばれるもので、BgetValuesetValue を持つオブジェクトでなければならない
  • remember { mutableStateOf(0) }MutableState<T> 型のインスタンスを返すが、この型とそのインタフェースである State<T> 自体には getValuesetValue の定義が含まれていない。これらは拡張関数として定義されており、androidx.compose.runtime.getValueandroidx.compose.runtime.setValue をインポートすることで使えるようになる
2
0
2

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
2
0