diadia

興味があることをやってみる。自分のメモを残しておきます。

Kotlin スコープとlateinitについて

参考

lateinit による変数の初期化

どんな場面でlateinitを使うのか

あるクラスのaメソッドの中で変数定義を行う。そして同一クラス内でbメソッドを作成するとする。この際に、aメソッドで定義した変数をそのままbメソッドで使うことはできない。なぜならaメソッドで行う処理とbメソッドで行う処理は別物であるからである。 そこでaメソッドとbメソッドで同一の変数を使うためには、クラスの属性定義で定めると同一の変数をaメソッドとbメソッドで定義する事ができる。

//このケースはメソッドbでエラーが出てしまう
class MyTest: Hoge(){

  fun a(){
    val hensuu:String = "hensuu" }

  fun b(){
    println("変数は"+hensuu) }
}
//エラーは解消される
class MyTest: Hoge(){

  var hensuu:String = "hensuu"
 
  fun a(){
    var hensuu:String = "hensuu_henka" }

  fun b(){
    println("変数は"+hensuu) }
}

上記の例で例えば、aメソッドで初めてhensuuの値を確定したいとする。その際は以下のようにnullを使う。

class MyTest: Hoge(){

  var hensuu:String? = null
 
  fun a(){
    var hensuu:String = "hensuu_henka" }

  fun b(){
    println("変数は"+hensuu) }
}

これで解決するが、kotlinの思想には変数は基本的にnull値を許容しない設計思想がある。そこで属性定義でnullを使わないで定義しようとすると以下になる。

//エラーが出てしまう
class MyTest: Hoge(){

  var hensuu:String
 
  fun a(){
    var hensuu:String = "hensuu_henka" }

  fun b(){
    println("変数は"+hensuu) }
}

上記の例ではエラーが出てしまう。それは変数定義の際にnullを含む何か値を決めてあげないといけないからである。 でもnullでも他の値を決めないで変数を定義したい。言い換えれば属性定義では値を定めず後でメソッド内で値を決めたい、このような要望を叶えるためにlateinitがある。

//エラーが解消される
class MyTest: Hoge(){

  lateinit var hensuu:String
 
  fun a(){
    var hensuu:String = "hensuu_henka" }

  fun b(){
    println("変数は"+hensuu) }
}

lateinitを使う際の制約

  • lateinit 変数は var で宣言しないといけない
  • lateinitで変数宣言するときにprimitive typeのデータ型は使用する事ができない。