araki tech

for developers including me

KotlinのMutableとImmutable【初学者向け】

KotlinのMutableとImmutable【初学者向け】

結論から言うと

  1. できる限りvalを使うこと
  2. 外部に公開するデータはImmutableにする
  3. 内部のみで扱うならばMutableでも可
  4. varとMutableの組み合わせは最悪

MutableとImmutableって何

簡単に言うと、Mutableは変更を許し、Immutableは変更を許さないものを指す。

Kotlinでは変数定義でこれをそれぞれvarvalで表すことができる。

変数定義

  • val … 読み込み専用の変数。Immutableな変数。
  • var … 読み書きできる変数。Mutableな変数。
val data1 = 100
var data2 = 100

data1 = 200  // できない
data2 = 200  // できる

変数はできるだけvalで定義し、不正な、あるいは思わぬ変更を考慮する必要は無くしたほうが良い

ちなみにvalはvalue (値)、varはvariable (変数)の略。

リストなど

Kotlinで標準利用できる、ListMapは明示的にMutableとImutableが分かれている。

val list1 = listOf(1, 2, 3)
val list2 = mutableListOf(1, 2, 3)

list1.add(4)  // できない
list2.add(4)  // できる

また、MutableListListを親クラスに持つので、MutableListListに特に明示的なキャストを書かずとも、アップキャストができる。

val list3: List<Int> = list2

ただし、中身 (参照) は一緒なのでlist2を変更すればlist3の中身も変更される。

この性質は意味ないように思えるが…

MutableとImmutableの使い分け

基本的に、publicなプロパティはImmutableであるべきである。

なぜなら、外部から容易に変更ができてしまい、不正な利用によって中身がめちゃくちゃにされてしまう恐れがあるから。

内部 (private) なプロパティであればMutbleで問題ない

でも、「変更が必要なデータを外部に公開したい時」がある。

例えばLiveDataなどはそのような状況がよくある。

そう言った時は、以下のように2つLiveDataを用意して、Mutable側のデータを外部に公開すれば良い。

// 内部で変更されるデータ
private val _data = MutableLiveData<Int>()

// 外部公開用のデータ
val data: LiveData<Int> = _data

一番最悪なパターン

Mutableでvar定義されたオブジェクト、さらにpublicならばそれは最悪な定義方法

var list = mutableListOf(1, 2, 3)

何かしら特定の理由がない限り、これはやらないようにする。

リストの中身が外部から変更される恐れがあるだけでなく、リスト丸ごと別なものに変えられてしまう恐れがある。

まとめ

  1. できる限りvalを使うこと
  2. 外部に公開するデータはImmutableにする
  3. 内部のみで扱うならばMutableでも可
  4. varとMutableの組み合わせは最悪