Edited at

Kotlinを1ヶ月使ってみた

More than 1 year has passed since last update.


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



コールバック引数

fun 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文だらけになる

実質書くならAndroid Studio固定になる

ビット演算など、演算子を使う場合はJavaの方が良さそう(toByteArrayや接中辞だらけになる)

whileの判別式で代入が出来ない

while(val hoge = 0) {

//↑できない
}



Slack

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