KotlinをAndroidで使ってみた

# Kotlinとは
https://kotlinlang.org/
![スクリーンショット 2017-01-19 8.22.53.png](https://qiita-image-store.s3.amazonaws.com/0/44174/71b2533a-db72-0a29-1fc8-2e91b0f571cb.png)

 - JVM上で動作する、Java言語と100%互換できる
 - Javaで冗長だった記述を短く書ける
 - Javaより安全に書ける
 - AndroidやTomCat等、Javaのフレームワークにも対応している

---

# Javaとの違い
## 書き方の違い
 - 変数
   - Javaで型宣言していたところはvar/valに統一できる。
   - (kotlinではデフォルトのアクセス制限がpublicになっている)

   ```java:変数.java
   public int i = 1;
   public MyObject obj = new MyObject();
   ```
         
   ```kotlin:変数.kt
   var i = 1 
   val obj = MyObject() <- newが必要ない
   ```

---

- メソッド
  - ほぼ書き方が同じ

   ```java:メソッド.java
    public String getFoo(){
        return "foo";
    }
   ```
         
   ```kotlin:メソッド.kt
    fun getFoo() : String {
        return "foo"
    }
   ```

---

- クラス
   - ほぼおなじだが、継承/実装元の指定方法を区別しない
   - 継承元の()は、コンストラクタの指定

   ```java:クラス.java
   public class MainActivity extends BaseActivity implements Listener {
   ...
   }
   ```
         
   ```kotlin:クラス.kt
class MainActivity : BaseActivity(), Listener {
        ...
   }
   ```

---

## 型推測
 - 変数の型は、最初に代入された型になる

   ```java:型推測.java
   public int i = 1;
   public double d = 2.0;
   public String str = "foo"
   ```
         
   ```kotlin:型推測.kt
   var i = 1 
   var d = 2.0
   var str : String = "foo" <- 型を宣言することもできる
   i = str <- コンパイルエラー(一度型が確定したら変えられない)
   ```

---

 - 型を書かなくていい分、型がわかりづらくなるので、返り値を返すメソッド名/受け取る変数名はわかりやすくする必要がある

   ```kotlin:型は何.kt
   var useCase = WifiStateUseCase()
   var flag = usecase.checkWifiStatus() <- boolean?Int?
   ```

---

## val
 - valはjavaでいうfinal(変数の変更不可)
 - 基本的にvalを使い、どうしても後で変更したい変数のみvarにする
   
   ```java:val.java
   public final String str = "foo"   
   ```
   
   ```kotlin:val.kt
   val str = "foo"
   str = "bar" <- コンパイルエラー
   ```

---

## null安全
   ```java:null安全.java
   public String str = null; <- OK
   int i = str.length; <- nullPointerException
   ```
   ```kotlin:null安全.kt
   var str : String? = null
   var i = str?.length <- nullが入る(落ちない)
   ```

---

 - nullかもしれない変数を区別して、nullだったときに落ちない用にしようという考え方
 - nullが存在しないという意味じゃない
 - String?のように、通常の型に?を追加する
 - 通常の型はnonNullとなり、以下のことを禁止できる
   1. nullの代入
   1. Nullableの代入
   1. Javaライブラリからの返り値の代入

         
   ```kotlin:nonNullとNullable.kt
   //var nonNull : String = null <- 1.コンパイルエラー
   var nullable : String? = null <- 通る
   //var nonNull : String = nullable // <- 2.コンパイルエラー
   ```

---

 - nullableのメソッドを呼び出すには、?.とする必要がある

   ```kotlin:null安全.kt
   //var i = nullable.length <- コンパイルエラー
   var i = nullable?.length <- Int?型が返る(nullになる)
   var ii = i++ <- iはnullableなので、コンパイルエラー
   ```
---

 - ?を!!にすることで「この変数は絶対nullじゃない」と宣言できる
 - NullPointerが発生する穴を生むので、使わない方がいい

   ```kotlin:null安全.kt
   var i2 = nullable!!.length <- nullPointerException
   ```

---

# AndroidでKotlin使ってみた
## ここ良かった
 - 「とりあえずval」ができる
   - javaでfinalは目立つ
   - 「これは変更しないな〜」って思って初めて付ける
 - useが便利
   - DBアクセス等で必要なclose処理を勝手にしてくれる
   
   ```Kotlin:use.kt
    override fun save(wifiState: WifiState) {
        Realm.getDefaultInstance().use { realm ->
            realm.beginTransaction()
            wifiState.id = getNextId()
            realm.copyToRealm(wifiState)
            realm.commitTransaction()
        }
    }
   ```
 - 開発時にNullで落ちない
  - 導入時に!!を使った時以外、移行後に落ちていない
 - 変数、メソッドが揃ってて見やすい
   - fun/var/valとみんな3文字＆型記述があとになるため、揃う
  ![スクリーンショット 2017-01-17 18.40.19.png](https://qiita-image-store.s3.amazonaws.com/0/44174/bb6a83e8-c337-e1b8-4126-5a7dbbbf6d79.png "スクリーンショット 2017-01-17 18.40.19.png")

 - Scalaみたく重くない
 - 静的言語の型推測がすごい楽

---
   
## ここ悪かった
 - Kotlin+DataBinding+XMLではまる
   - DataBindingでミリ秒を時刻表示するためにDataUtilクラスを使った
   - KotlinでJavaでいうStaticメソッドを使うには@JvmStaticアノテーションが必要だった
   - なのに、「DataBindingの構築に失敗しました」としかでないから、KotlinでDataBindingを使うための設定をいじったりしてた
   - エラーが出ても丁寧な情報がネットに載ってないので、情報を正しく得る力が必要

---

## 所感
   - AndroidStudioの言語サポートもJavaと変わらないくらい便利になっている
   - nullで落ちなくなるのは開発も早くできる
   - valとかnull安全とか有効に使うためには、MVCとかMVVMとかの導入が必要かなと思った
     - AndroidライブラリがJavaなので、Activityに処理を書くと意味がない
     - View層、Model層って分けないとvarばかり必要になる

---

## まとめ
 - 書き方に違いはあるが、大抵コード量が少なくなるようになる
 - nullで落ちなくなる
 - 書いてて楽しい言語
 - いつかプロダクトでも導入したい