Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【Kotlin】【Android】Null安全でぬるぽに立ち向かう

 【Kotlin】【Android】Null安全でぬるぽに立ち向かう

2016.07.09 Kansai.kt #1 用資料です。KotlinのNull安全について調べたことをまとめています。

masanori_msl

July 09, 2016
Tweet

More Decks by masanori_msl

Other Decks in Programming

Transcript

  1. Null許容(Nullable) 非Null許容型の変数に、Null許容型の変数を代入 するには、後者がNullでないことを保証する必要 がある。 var nullableText: String? = "Not null"

    var notNullableText: String = nullableText!! // OK ※ ではこれは...? var nullableText: String? = null var notNullableText: String = nullableText!!
  2. Null許容(Nullable) Kotlinではlateinitを付けることで、変数の初期化 のタイミングを変更できる。 … この変数を初期化せずに使うと ? lateinit var lateinitNotNullableText: String

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var notNullableText: String = lateinitNotNullableText var length = lateinitNotNullableText.length }
  3. Null許容(Nullable) UninitializedPropertyAccessExceptionが発生 する lateinit var lateinitNotNullableText: String override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var notNullableText: String = lateinitNotNullableText // NG ※ var length = lateinitNotNullableText.length // NG ※ }
  4. Null許容(Nullable) Javaのコード上ではNull許容型・非Null許容型の 制限が強制されない。 MainActivity.kt NotNullClass.java - 省略 - public String

    getText(){ return null; // 実行可能 } - 省略 - val notNullableClass = NotNullableClass() val notNullableText: String = notNullableClass.getText() }
  5. 非Null許容型にする Nullにならないことを保証できる変数は、Nullを 許容しないことでコードをシンプルにできる。 class MainActivity : AppCompatActivity() { var notNullableText:

    String = "" // Nullを代入しない override fun onCreate(savedInstanceState: Bundle?) { - 省略 - var length = NotNullableText.length // Nullチェックが不要 } } 引数にも適用可能だが、特にコールバックで呼ば れた時に本当にNullが渡されないか確認が必要。
  6. lateinit Nullにならないことは確実だが、宣言時に値が入 れられない変数ではlateinitを使う。 class MainActivity : AppCompatActivity() { lateinit var

    notNullableClass: NotNullableClass // 後で初期化 override fun onCreate(savedInstanceState: Bundle?) { - 省略 - // 宣言時に値が入れられない場合も非Null許容型にできる notNullableClass = NotNullableClass() } }
  7. Nullチェック class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { - 省略 - var nullableText: String? = “Not null” var length = -1 if(nullableText != null){ // Nullチェック // Nullをチェックしているので // ”!.”を使っても安全にlengthを実行可能 length = nullableText!.length } } } 通常のNullチェック
  8. Nullチェック class MainActivity : AppCompatActivity() {  val nullableText: String? =

    “Not null” override fun onCreate(savedInstanceState: Bundle?) { - 省略 - var length = -1 if(nullableText != null){ // Nullチェック // Nullで無いことが保証されるので // 非Null許容の変数と同じように扱うことが可能 length = nullableText.length } } } valを使ってimmutableにできる場合
  9. Nullチェック class MainActivity : AppCompatActivity() {  val nullableText: String? =

    “Not null” override fun onCreate(savedInstanceState: Bundle?) { - 省略 - var length = -1 if(nullableText == null){ // Nullチェック return // Nullなら以下の処理をスキップ } // 非Null許容の変数と同じように扱うことが可能 length = nullableText.length } } これもOK
  10. Nullチェック class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { - 省略 - var nullableText: String? = “Not null” var length = -1 if(nullableText != null){ // Nullチェック // Nullで無いことが保証されるので // 非Null許容の変数と同じように扱うことが可能 length = nullableText.length } } } ローカル変数ならmutableな変数でもOK
  11. ?演算子 Null ” 許容型の変数では、 ?.”を使うことで安全にア クセスできる。 class MainActivity : AppCompatActivity()

    { override fun onCreate(savedInstanceState: Bundle?) { - 省略 - val nullableText: String? = “Not null” // nullableTextならNullが // それ以外はnullableText.lengthの値が入る var length = nullableText?.length } }
  12. ?演算子 ”?.”を使ったチェーンメソッド class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState:

    Bundle?) { - 省略 - val nullableText: String? = “Not null” // nullableText、lengthのどちらかがNullならNullが入る var lengthText = nullableText?.length?.toString() } }
  13. 疑問 この2つのコード、結果は同じ。 var nullableText: String? = “Not null” var nullableNum1:

    Int? = null var nullableNum2: Int? = null // Code 1 if(nullableText != null){ nullableNum1 = nullableText.length NullableNum2 = nullableText.length } // Code2 nullableNum1 = nullableText?.length nullableNum2 = nullableText?.length 実行速度に違いはある?
  14. 計測 class MainActivity : AppCompatActivity() { lateinit var logger: TimingLogger

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // ログの取得開始. logger = TimingLogger("KtTimingLogger", "Code") // getLengthOfCode1()またはgetLengthOfCode2()を実行 // 測定を終了してログ出力する. logger.dumpToLog() } android.util.TimingLoggerを使って計測
  15. 計測 fun getLengthOfCode1(){ // Code1の検証. var nullableText: String? = "not

    null" var nullableNum1: Int? = null var nullableNum2: Int? = null for(i in 0..1000000) { if (nullableText != null) { nullableNum1 = nullableText.length nullableNum2 = nullableText.length } } logger.addSplit("Code1おしまい") }
  16. 計測 fun getLengthOfCode2(){ // Code2の検証. var nullableText: String? = "not

    null" var nullableNum1: Int? = null var nullableNum2: Int? = null for(i in 0..1000000) { nullableNum1 = nullableText?.length nullableNum2 = nullableText?.length } logger.addSplit("Code2おしまい") }
  17. Elvis演算子 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { - 省略 - var nullableText: String? = null // nullableTextがNull ” の場合のみ ?:”の右の値を代入する nullableText = nullableText?: “Null ” でした // 今回はローカル変数なので、もう一度nullableTextに   // Nullチェック不要を入れるまではNullチェック不要 } } ”?:”を使うことで、変数がNullの場合のみ値を代入 できる。
  18. Elvis演算子 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { - 省略 - var nullableText: String? = null // 変数がNullなら以降の処理をスキップ nullableText?: return - 省略 - } } ”?:”を使うと変数がNullの場合はreturnする、とい うことも可能。
  19. 参考 5.4 NULL 安全 - プログラミング言語Kotlin 解説 16 日目:ぬるぽとの別れ -

    Kotlin Advent Calendar 2012 (全部俺) Reference - Kotlin Programming Language 30分で覚えるKotlin 文法 - Qiita https://kotlinlang.org/docs/reference/ https://sites.google.com/site/tarokotlin/chap5/sec54 http://kotlin.hatenablog.jp/entry/2012/12/16/001635 http://qiita.com/k5n/items/cc0377b75d8537ef8a85 http://qiita.com/datsnet/items/1b868ced7c2fa8b4dcb0 処理時間の計測をAndroid で簡単に行う - Qiita
  20. Credit Google Noto Fonts  Main Page:  License: Material

    icons  Main Page:  License: https://www.google.com/get/noto/ SIL Open Font License (OFL) https://design.google.com/icons/ CC-BY License