Kotlinを1ヶ月使ってみた

  • 97
    いいね
  • 6
    コメント

Kotlin

kotlin_250x250.png

iOS大好きマンがkotlinを1ヶ月触った結果
↑iOSアプリ開発歴5年くらい、Javaはあんまり触ったことがない。1年間だけAndroid(Xperia)だった期間あり。


Kotlinとは

JetBrains(IntelliJの開発元)が開発した言語S6

Java → コンパイル → Javaバイトコード→ Android
Kotlin → コンパイル → Javaバイトコード → Android

という立ち位置なのでJavaとほぼ完全な互換性がある。
(因みにJavascriptにもコンパイルできる)


強力なIDE

SwiftとXcodeが強力なように、KotlinもAndroid Studioとの連携が非常に強力
Javaと同じようにimport補助が出来る他interfaceの一括設置、kotlin風関数呼び出し補助、
Javaファイルをkotlinにコンバートも出来る。


言語仕様

Javaに比べたらSwiftに似ているのでiOSエンジニアなら取り掛かりやすい。
と言っても実はKotlinの方が少し先にリリースされている。
簡単なところからいくつか紹介


変数宣言

java
JavaObject javaObject = new JavaObject("android");
kotlin
val kotlinObject = KotlinObject("android")

型推論と定数宣言、オプショナル定義もすっきり


定数/変数

var fuga = "neko"
fuga = "inu" //再代入可

val hoge = "neko"
hoge = "inu" //できない

finalを付けずとも再代入を防げる


オプショナル1

var fuga: String? = "neko"
fuga = null //再代入

var hoge: String = ""
hoge = null //できない

nullを許容するか厳しく書ける


オプショナル2

hoge?.anything()

hogeがnullだと何も起こらない


コンストラクタ1

constructor() {
 //初期化処理
}

初期化の際にわざわざクラス名を書かなくて良い。
変数宣言と共にとても良い…


コンストラクタ2

class AudioFormat(val type: String) {
}

プライマリコンストラクタはクラスの宣言に書くことが出来て、また変数としての宣言も出来る。

...ってくらいにして


Try

Kotlinはとにかくすっきり書けるって事。

http://try.kotlinlang.org

で簡単に試せる。javaからの自動変換もある。
サクッとコードを変換したい時や試したい時に便利


実際使って便利だったやつ


Java関数のプロパティ風呼び出し

class JavaObject {
  String getMessage() {
    return "message";
  }
  void setMessage(String message) {
    this.message = message
  }
}

のようなメソッドを

javaObject.message //get
javaObject.message = "hello" //set

と呼び出せる。
ライブラリとかでJavaが混じっていてもkotlinの流儀を貫ける


extension

fun Message.say() {
  playVoice()
}

既存のクラスにメソッドが生やせる

val PreviewActivity.voiceId: Int
  get() = 0

プロパティも生やせる(Swiftだと出来ない)


言語レベルのシングルトンサポート

object SingletonClass {
  var isFirstLaunch = false
}

classをobjectと書くだけでシングルトン化
SingletonClass.isFirstLaunch
のようにクラス名.プロパティと言った風に呼ぶ


小規模interfaceの省略

button.setOnClickListener(object :View.OnClickListener {
    override fun onClick(v: View?) { 

    }
})

このようなオーバーライドを1つしか必要としないinterfaceは

button.setOnClickListener { 
}

このように省略することが出来る。
引数はitで取得可能


getter/setter

var messsage: String = ""
    set (value) {}
    get {}

getter/setterを明示的につけることも出来る。
setterはfield = valueとすることで循環させずにセットでき、簡易的なKVOとしても扱える。


Layout xmlとの連携

<Button android:id = "+@id/button" ~ />

とか書いておくと

button.text = ""

このようにid名のインスタンスを定義せずに使うことが出来る


this@,return@

class A {
    val message = "hello"
    class B {
        val message = "world"
        fun action() {
            this@A.message      
            this@B.message
        }
    }
}

this@でthisの意味を明示的に表記出来る

button.setOnClickListener {
  ary.map {
    //一気にreturnすることも出来る
    return@setOnClickListener
    //もちろん普通にreturnも出来る
    return@map false
  }
}

返り値の必要な関数内ではどこにいても一気にreturnすることが出来る。


when

val word = when (value) {
  0 -> "zero"
  1 -> "one"
}

返り値付きのswitchみたいなやつ
returnもclosureも使えるので非常に使いやすい
EventBusなどでState管理する時のビューの見た目等で使った

when (value) {
  o -> "zero"
  1,2 -> "one or two"
  else -> {
   throw new Exception()
  }
}

条件分岐も上手


これってどうやって書くの


nullのアンラップ (if let風味)

hoge?.let {
  it.action()
}
hoge?.let {
    it.action()
} ?: run {
    //nullの場合
}

という書き方も一応出来る


nullのアンラップ (guard風味)

var hoge = hoge ?: return

コールバック引数

func action(completion: (() -> Unit)? = null)

(() -> Unit)を型として宣言。
例えば((Int) -> String)であればIntを受け取ってStringを返すコールバック

completion?.invoke()

で実行。


初期化の約束

private lateinit var message:String

onCreate() {
  message = "hello"
}

lateinitを使うと、notnullなグローバル変数を初期化せずに宣言出来る。
必ずonCreateやコンストラクタで初期化すると保証出来るときはこれを使うことでnull-wrapの回数を減らせる


気になるアレ


runtimeのサイズ

スクリーンショット 2016-06-28 9.49.09.png

良さ


コンパイル時間

感覚値ではそんなに気にならない。早くもないし遅くもない


まとめ


メリット

とにかくすっきり書ける
IDEのおかげで実は学習コストは少ない
Javaとの互換性が高いのでプロジェクトの小さいところから入れやすい


デメリット

nullの扱いをしっかりしないとnull判別のif文だらけになる
実質書くならAndroidStudio固定になる
ビット演算など、演算子を使う場合はJavaの方が良さそう(toByteArrayや接中辞だらけになる)
whileの判別式で代入が出来ない

while(val hoge = 0) {
   //↑できない   
}

Slack

http://kotlinlang-jp.herokuapp.com/