Kotlinについて学んだ [Kotlin助走読本の要約]
概要
- kotlinを書くことになった
- kotlinユーザーグループという団体がKotlin助走読本を無料で配布している
- 先輩に進められたので読んだ
- 読むだけだと頭に入らないので簡単に要約した
- 本体も86pと大分要約された本なので是非読んでみることをおすすめすする
- 勉強になりました、kotlinユーザーグループの方々ありがとうございます
1章 Kotlinについて知る
1.1 Kotlinとは
- KotlinはJetBrain社がJavaに代わり、より簡潔に書くことを目的として作られた静的型付き言語
- JavaだけでなくJavascriptへのトランスパイルも可能
- Javaと相互運用するように設計されているのでJavaプロジェクトの一部でKotlinを使うことも出来る
- Androidで公式サポートされている
Kotlinを使うと何が嬉しいのか
Androidとの親和性が高い
生産性が高い
メンタビリティが高い
- Null許容の判定を言語レベルで扱っているため、コンパイル時にNullPointerExceptionの部分が分かる
1.3 Kotlinの特徴
静的型付け言語
対象のプラットフォーム
-
- 関数オブジェクトを引数にしたり戻り値にしたりできる
fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { // 引数で渡された関数オブジェクトを実行している return body() } finally { lock.unlock() } }
- ラムダ式
- 関数を宣言せずに関数オブジェクトを生成できる
max(strings, { a, b -> a.length < b.length })
1.4 将来の展望
JetBrain社としての展望
- Andoid, iOS, サーバーサイド, Webフロントエンド, ネイティブなど各種プラットフォーム開発を目指している
AndroidとKotlin
- 2017年にAndroid公式開発言語としてサポートされた
- 今後も様々なサポートやツールが増えることが予想される
1.5 導入事例
- Expedia
- Pintarest
- Retty
- Pairs
第2章 Kotlinを学ぶ
環境構築からHelloWorldまで
環境構築
javaの場合はエントリーポイントとなるmainメソッドを定義するためにはclassを定義してそのstaticメソッドとして定義する必要があったが、Kotlinはトップレベルに関数を定義できる
- 関数定義はfunで始まる
- 引数の型は後ろに置く
- セミコロンが不要
- Javaでいるvoid型のメソッドはUnit型と定義され、戻り値の記述を省略できる
fun main(args: Array<String>) { println("Hello, ${args[0]}!") }
- 文字列中に$とともに変数や式を挿入するとそれを評価した値を文字列として連結してくれる
val i = 42 // 変数 i に 42 を代入 val s = "すべての答え:$i" // -> すべての答え:42 val s1 = "1 + 1 は${ 1 + 1 }です。" // 1 + 1 は 2 です。 val s2 = "s1 の⻑さは${s1.length}です。" // s1 の⻑さは 10 です。
classの定義
- クラス名の後に:を次ぐけて継承元のクラスを記述する
- 何も指定しない場合はpublicスコープなクラスとなる
クラスのメソッド
- オーバーライドメソッドはfunの前にoverrideという修飾子をつける
null許容型
- 型の後ろに?があるものはNull許容型であることを示している
2.2 Kotlinの味見
基本文法
- 変数宣言
- varで宣言すると再代入が可能
- valで宣言すると再代入ができない
val num : Int = 1 num = 2 // =>コンパイルエラー var num2 : Int = 2 num2 = 3 // =>コンパイルエラーにならない
- 型推論
- 型を省略できるのは便利ではありますが、開発者同士で分かりにくい場合は明示的に宣言する方がよい
val num = 1
- if文は式としても扱うことが出来る
val result : String = if(true) {"true"} else { "false" } println(result) // =>true // else 節のない場合は、値を返さない Java と同じような if 文として扱われる
- siwtch文の代わりにwhen式を使う
- 条件のうち、必ずどれか 1 つに一致する必要がある
- 左側を条件式にすることも可能
val value = 1 when { value == 1-> println("one") value == 2-> println("two") else -> println("other") }
for文
- mapOf: マップを生成する関数
- listOf: リストを生成する関数
- setOf: セットを生成する関数
for(i in 0..4)
のようなRangeを使った書き方for(i in 4 downTo 0)
のような逆順ループ
white, do-whileもJava同様に使える
Null安全
- kotlinにおける通常の型はnullの代入を許容しない
nullを許容するには型の後ろに?をつける
nullチェックと安全な呼び出し
val l : Int? = b?.length var b: String? = "abc" val l : Int = if(b != null) b.length else -1 val l : Int = b?.length ?: -1 val l : Int = b!!.length
関数
- 関数はfunを使って定義する
関数名: 型
というフォーマットで引数を宣言する- 引数はコンマで分ける
- 戻り値がUnit型以外のときは戻り値も定義しなければならない
- 引数のデフォルト値は型定義のあとに=を書いて定義する
- 名前付き引数も使える
- 名前付き引数を使った場合、後に続く引数は全て名前付きにしなくてはならない
- 関数名の前に<>を使うことで型パラメーターを使うことも出来る
fun add(x: Int, y: Int): Int { return x + y } fun add(x: Int, y: Int): Int = x + y fun add(x: Int, y: Int) = x + y fun <T> singletonList(item: T): List<T>{}
- 高位関数
- 関数の引数や戻り値に関数オブジェクトを使う関数
- 具体的な処理を関数の外に出すことによって凡庸化できるようにする
fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { return body() } finally { lock.unlock() } }
max(strings, { a, b -> a.length < b.length }) max(strings) { a, b -> a.length < b.length }
- インライン関数
- 実行時に関数オブジェクトを生成するとメモリコストが高くなる場合がある
- funの前にinlineをつけることに よってコンパイル時にインライン展開されるようになる
inline fun lock<T>(lock: Lock, body: () -> T): T { // ... }
クラス
class クラス名 {}
で定義できる- クラスにメンバやメソッドが無い場合は波括弧を省略できる
val myClass = MyClass()
のようにnew無しでインスタンス生成できる- コンストラクタ
class Person(val name: String) { init { logger.info("name = ${name}") } constructor(name: String, parent: Person) : this(name) { // 処理 } }
- メソッドはクラス内に関数を定義すればいい
- Kotlinでフィールドを定義するとバッキングフィールドというものが生成され、実際の値は底に格納される
- 要するにプロパティを定義するだけで getter, setter が自動生成される
- 自分でgetter/setterを定義することもでき、これを定義した場合はバッキングフィールドは定義されない
- DIなどを利用していてインスタンス生成時に値を設定することが出来ない場合はlateinitキーを使うことで初期化を遅らせることが出来る
- classの代わりにobjectキーをつかうことによってインスタンスが必ず1つしか生成されないシングルトンなクラスを定義できる
- KotlinではJavaのようなstaticなメンバを定義することができない
- インスタンスを生成しなくても利用できるメンバを定義したい場合は companion object キーを使う
- open修飾子が付いているクラスについては:で継承することができる
- 継承元のメソッドを上書きするときは、継承するメソッドと同じ名前のメソッドを定義し、override修飾子をつける
- Javaと同様にファイルの戦闘でpackageキーを使うことでクラスなどの要素を名前空間で区切ることが出来る
*アクセス制限
- public: デフォルトの設定で公開範囲に制限はない
- internal: 同一モジュール内に限り全公開
- private: 同一ファイル内のみアクセス可能
データクラス
- data クラスを定義すると次のメソッド自動で生成する
- equals()
- hasCode()
- toString()
- vomponentN()
- 1から始まるメンバー変数の順番
- copy()
- メンバー変数が同じインスタンスを作る
- data クラスの制限
- インスタンスを分解して幾つかの変数に代入する分解宣言ができる
インターフェイス
拡張
- 拡張関数
- 任意の方に対して外部から関数を追加できる機能
- 関数を追加したい方を関数名の手前に付け加えると定義できる
- 拡張プロパティ
- 拡張関数とおなじように任意のプロパティを外付けできる
- 同一ファイル外から呼ぶ場合はimportが必要になる
- 四則演算のようなモノを新しい方にも適用できるよにする演算子オーバーロードという仕組みがある
- plusというメソッドが定義されていれば+という二項演算子をつかった計算を行うことができる
イコール
- 同じ参照であるかを調べるときも同じオブジェクトの中身であるかを調べるときも == 演算子を使う
型エイリアス
- typealiasキーを使うことで既存の型に別名をあたえることができる
### 2.3 JavaからKotlinへの移行 * javaとkotlinは相互互換がある * KotlinとJavaを混在させる * メンテナンスコストがあがる * 境界を設けたほうが良い * kotlinからjavaを使うときの注意点 * javaでは予約語ではないがkotlinでは予約度なキーワードをバックフォーとでエスケープする * javaにはnull許容型がないため、呼び出し時に判断を求められる * 検査例外を無視するので意識してtry-catchなどを書くことが必要となる * javaからkotlinを使う * getter, setterが定義されているのでメンバ変数にはそれを用いてアクセスする * ラムダ式はSAM インターフェースに変換される * 拡張関数は対象のクラスを第一引数に取る関数が宣言されているという扱いになる * kotlin上でデフォルト引数を持っている場合でも全ての引数を渡す必要がある * デフォルト引数のある関数をオーバーロードするには@JvmOverloadsアノテーションを使う
3章 次のステップ
3.1 学習方法
- 公式ページ
- KotlinWeekly
- について学びたい方におすすめなのは、書籍「Kotlin スタートブックー新しい Android プログラミングー(2016)⻑澤太郎著 リックテレコム
- Kotlin Koans online
- Google I/O 2017 : Introduction to Kotlin(和訳/要約)
3.2 コミュニティ
- 日本Kotlinユーザーグループ
- kotlin slack
- kotlin conf
3.3 次回リリースの予告
- 今回のリリースが最初で最後というわけではない
- 少なくとも継続して新バージョンをリリースすることを検討している