Slide 1

Slide 1 text

はじめての Kotlin ハンズオン

Slide 2

Slide 2 text

もくじ 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 3

Slide 3 text

このハンズオンで... Kotlinって良い言語って聞くけど 何が良いのか どうやって始めるのか どうやって書くのか 次のステップは?

Slide 4

Slide 4 text

このハンズオンで...こうなる! わかる! 進める!

Slide 5

Slide 5 text

長澤 太郎 ● エムスリー株式会社 ● 日本Kotlinユーザグループ代表

Slide 6

Slide 6 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 7

Slide 7 text

Kotlinとは? ● 静的型付けオブジェクト指向言語 ● ターゲット: Java仮想マシン、Android、JavaScript、 ネイティブ ● 開発元: JetBrains ● 2011年7月発表、2016年2月正式リリース ● Apache License ver 2.0 Better Java

Slide 8

Slide 8 text

Kotlinの特徴 簡単 文法、コードの見た目がわかりや すい。学習コストが低そう 安全 型安全、Null安全 Android Googleのお墨付き! Interop KotlinからJavaコードを、Javaから Kotlinコードを相互に呼び出せる

Slide 9

Slide 9 text

簡単!Better Java ユーザを表現するUserクラス  ・name: 名前  ・id: 識別キー。nullの可能性あり こんなクラスが 欲しいな!

Slide 10

Slide 10 text

簡単!Better Java public final class User { private final Long id; private final String name; public User(final Long id, final String name) { this.id = id; this.name = name; } public Long getId() { return id; } public String getName() { return name; } @Override public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; final User user = (User) o; if (!id.equals(user.id)) return false; return name.equals(user.name); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); return result; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } } 筋力と視力が 重要だ... Javaで書くと...

Slide 11

Slide 11 text

簡単!Better Java data class User(val name: String, val id: Long?) サイコー以外の 言葉が見つから ない Kotlinで書くと...

Slide 12

Slide 12 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 13

Slide 13 text

Try Kotlin ● http://try.kotl.in ● ブラウザ上で試せる開発環境

Slide 14

Slide 14 text

Hello World package sample fun main(args: Array) { println("Hello, world!") }

Slide 15

Slide 15 text

課題の回答を共有しよう! 1. ログイン 2. My programs にフォルダを作っ てファイルを置く 3. コードを書く 4. URLを共有する

Slide 16

Slide 16 text

解答例は公開済み! https://goo.gl/QgCVUM

Slide 17

Slide 17 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 18

Slide 18 text

基本的にはJavaにそっくり fun main(args: Array) { println(123) // 123 println(10 + 2 * 3) // 16 println(5 / 2.0) // 2.5 println(true && true) // true println('A') // A println("Hello".toUpperCase()) // HELLO }

Slide 19

Slide 19 text

変数宣言のための2つのキーワード ● val … 再代入NGな変数を宣言する ● var … 再代入OKな変数を宣言する fun main(args: Array) { var count: Int = 0 count++ println(count++) // 1 }

Slide 20

Slide 20 text

推論できるところは大抵 型を省略できる ● 関数の戻り値の型 ● ラムダ式の引数の型 ● 型引数 val hoge = "I love Kotlin" val fuga = hoge.reversed() val piyo = fuga.length この他に などが省略可能な場合がある

Slide 21

Slide 21 text

文字列リテラルが便利だよ! val name = "おにぎり" val price = 120 println("${name}が3個で${price * 3}円です") val html = """

Hello, world!

""" println(html) 文字列テンプレート raw-string

Slide 22

Slide 22 text

if-else: Javaとほぼ同じ fun main(args: Array) { if (args.size > 0) { println("こんにちは、${args[0]}さん") } else { println("こんにちは、名無しさん") } }

Slide 23

Slide 23 text

if-else: Kotlinでは式である fun main(args: Array) { val name = if (args.size > 0) args[0] else "名無し" println("こんにちは、${name}さん") }

Slide 24

Slide 24 text

forループ fun main(args: Array) { val names = listOf("foo", "bar", "baz") for (name in names) { println(name) } }

Slide 25

Slide 25 text

forループ fun main(args: Array) { val names = listOf("foo", "bar", "baz") for (name in names) { println(name) } } リストを生成する関数

Slide 26

Slide 26 text

forループ fun main(args: Array) { val names = listOf("foo", "bar", "baz") for (name in names) { println(name) } } 繰り返し可能なオブジェクトに対して 要素を順に取り出す

Slide 27

Slide 27 text

レンジ fun main(args: Array) { var sum = 0 for (i in 1..10) { sum += i } println(sum) // 55 }

Slide 28

Slide 28 text

レンジ fun main(args: Array) { var sum = 0 for (i in 1..10) { sum += i } println(sum) // 55 } 「1から10まで」のレンジ(範囲) オブジェクトを生成する

Slide 29

Slide 29 text

whileループ: Javaとほぼ同じ fun main(args: Array) { var count = 3 while (count >= 0) { println(count--) } }

Slide 30

Slide 30 text

[課題] FizzBuzz ● 1から100までをプリントする。ただし: ○ 3で割り切れる数は、その数字の代わりに「Fizz」をプリントする ○ 5で割り切れる数は、その数字の代わりに「Buzz」をプリントする ○ 3と5それぞれで割り切れる数は、その数字の代わりに 「FizzBuzz」をプリントする

Slide 31

Slide 31 text

[課題] 世界のナベアツ問題 ● 1から40までの数をプリントする ● 3の倍数の場合「!」を後ろに付ける ● いずれかの桁に3を含む数の場合も「!」を付ける 1 2 3! 4 5 6! 7 8 9! 10 11 12! 13! 14 15! 例

Slide 32

Slide 32 text

まとめ ● リテラルや演算子などはJavaにそっくり ● 再代入OKな変数宣言 var、再代入NGな変数宣言 val ● 型推論により型の記述を省略可能 ● 文字列リテラルが便利: 文字列テンプレート、raw-string ● if-elseは式である ● forループは、Javaの拡張for文に似ている ● listOf関数により、リストをつくることができる ● 範囲を表すレンジオブジェクト (e.g.) 1..5 ● whileループは、Javaとほぼ同じ

Slide 33

Slide 33 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 34

Slide 34 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 35

Slide 35 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 } これが関数

Slide 36

Slide 36 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 } 関数を定義するためのキーワード

Slide 37

Slide 37 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 } 関数の名前

Slide 38

Slide 38 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 } 引数リスト

Slide 39

Slide 39 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 } 戻り値の型

Slide 40

Slide 40 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 41

Slide 41 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 42

Slide 42 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 43

Slide 43 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 44

Slide 44 text

関数入門 fun add(a: Int, b: Int): Int { return a + b } fun main(args: Array) { val sum = add(3, 7) println(sum) // 10 }

Slide 45

Slide 45 text

単一式関数 fun add(a: Int, b: Int): Int { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b 型を省略するのは楽だけど 明示した方が読み返したときに わかりやすい!

Slide 46

Slide 46 text

[課題] いろんな関数をつくって遊ぼう 下記の様な関数を作る。 ● 引数として与えられた整数を2乗した数を返す関数square ● 引数として与えられた2つの整数のうち、大きい方を返す 関数max ● 引数として与えられた整数が偶数の場合にtrueを、それ 以外の場合にfalseを返す関数isEven ● 引数として与えられた整数の階乗を返す関数factorial ○ 例)4の階乗 = 4 * 3 * 2 * 1 ● 引数として与えられた整数に、3が含まれるかどうかを返 す関数containsThree

Slide 47

Slide 47 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 48

Slide 48 text

クラスの定義 class Person(val name: String) val taro: Person = Person("Taro") println(taro.name) // Taro

Slide 49

Slide 49 text

クラスの定義 class Person(val name: String) val taro: Person = Person("Taro") println(taro.name) // Taro クラスの定義 インスタンス生成=コンストラクタ呼び出し

Slide 50

Slide 50 text

クラスの定義 class Person(val name: String) val taro: Person = Person("Taro") println(taro.name) // Taro プライマリコンストラクタとその引数リスト

Slide 51

Slide 51 text

クラスの定義 class Person(val name: String) val taro: Person = Person("Taro") println(taro.name) // Taro プロパティ

Slide 52

Slide 52 text

メソッドの定義 class Person(val name: String) { fun introduceMyself() { println("I am ${name}") } } val taro: Person = Person("Taro") taro.introduceMyself() // I am Taro

Slide 53

Slide 53 text

[課題] クラスの定義 ● クラス名 IntPair ● 2つのプロパティを持つ ○ first: Int ○ second: Int ● 3つのメソッドを持つ ○ sum: firstとsecondの和を返す ○ max: firstとsecondのうち大きい方を返す ○ swap: firstとsecondが逆になったIntPairオブジェクトを返す

Slide 54

Slide 54 text

クラスが実装すべき便利メソッド class IntPiar(val first: Int, val second: Int) { // 省略 override fun toString(): String = "IntPair(first=$first, second=$second)" } ● toStringメソッド ● equals/hashCode   → 機械的に導き出すことができる

Slide 55

Slide 55 text

データクラス data class IntPiar(val first: Int, val second: Int) { // 省略 } fun main(args: Array) { val oneAndTwo = IntPair(1, 2) println(oneAndTwo) // IntPair(first=1, second=2) println(oneAndTwo == IntPair(1, 2)) // true println(oneAndTwo === IntPair(1, 2)) // false }

Slide 56

Slide 56 text

拡張関数 fun String.hello() { println("Hello, ${this}!") } val name = "world" name.hello() // Hello, world!

Slide 57

Slide 57 text

拡張関数 fun String.hello() { println("Hello, ${this}!") } val name = "world" name.hello() // Hello, world! 「クラス名.」がミソ

Slide 58

Slide 58 text

拡張関数 fun String.hello() { println("Hello, ${this}!") } val name = "world" name.hello() // Hello, world! メソッドのようにthisが使える this: 自分自身への参照

Slide 59

Slide 59 text

拡張関数 fun String.hello() { println("Hello, ${this}!") } val name = "world" name.hello() // Hello, world! メソッドのように呼び出せる

Slide 60

Slide 60 text

[課題] 拡張関数との出会い ● 拡張関数 meets ○ Intに対する拡張関数 ○ Int型の引数を1つ取る ○ 自身がfirstに、引数がsecondになるIntPairオブジェクトを返す

Slide 61

Slide 61 text

まとめ ● クラスやオブジェクト、インスタンスの考え方はJavaとほぼ同じ ● クラスはプライマリコンストラクタを持つ ● クラスはメソッドを持つことができる ● クラスはプロパティを持つことができる ● プライマリコンストラクタの引数を、そのままプロパティとして宣 言することができる ● インスタンス生成の際にnewのようなキーワードは不要 ● 既存のクラスにメソッドを追加するような「拡張関数」というもの を定義できる

Slide 62

Slide 62 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全

Slide 63

Slide 63 text

Null安全 ● nullの可能性のあるものと、そうでないものを厳格に 区別することでケアレスミスを防ぐ ● nullの可能性のない型(NotNull) ● nullの可能性のある型(Nullable) ?をつけて表現 val a: Int = null // コンパイルエラー val b: Int? = null // OK b.toString() // コンパイルエラー

Slide 64

Slide 64 text

Nullableの扱いは、とことん慎重に val s: String? = getString() s.length // コンパイルエラー これを許してしまうと NPEの原因になる

Slide 65

Slide 65 text

if文などによるnullチェック if (s != null) { s.length } nullでないことが保証される文脈 ではNotNullとして扱える

Slide 66

Slide 66 text

安全呼び出し s?.length if (s != null) s.length else null 同じ if-elseは式 (評価されて値になる) foo?.bar()?.baz()?.qux() メソッドチェーンで役立つ

Slide 67

Slide 67 text

[課題] nullを許容するプロパティ ● IntPairクラスを元にNulltableIntPiarを定義する ○ プロパティfirstとsecondがnullを許容する ○ 各メソッドの戻り値はnullを許容しない ○ そのとき、nullの値はゼロと見なす ■ (e.g.) first=5, second=nullのとき sum()は5を返す

Slide 68

Slide 68 text

1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト 6. Null安全 7. おまけ

Slide 69

Slide 69 text

AndroidでKotlinを始める チェックを入れるだけ

Slide 70

Slide 70 text

Android StudioがKotlinを教えてくれる Javaコードのペーストで Kotlinコードに変換

Slide 71

Slide 71 text

書籍 今日のハンズオンを難しく感じなければ 「Kotlinスタートブック」 Kotlinの文法のほとんどをカバーして いるが、若干古いのが難点。 言語自体に関心が強く、Javaに詳しければ 「Kotlinイン・アクション」 Kotlinのすべてを知れると言っても過言ではな い。Kotlin 1.1にも対応しているが、1.2で登場した 機能は言及されていない。

Slide 72

Slide 72 text

もっと課題やりたいなら Kotlin Koans

Slide 73

Slide 73 text

今日登場しなかったキーワード ● インタフェース ● 抽象クラス ● ラムダ式 ● 委譲プロパティ ● シールドクラス ● 列挙型 ● ジェネリクス ● コルーチン ● クラス委譲 ● 演算子オーバロード など...

Slide 74

Slide 74 text

本日のまとめ ● KotlinはBetter Java(とはいえJSやNativeも対象) ● Kotlinの特徴は、簡単・安全・Android対応・Javaとの親和性 ● Javaと似ている文法も多くある ● 強力な型推論、文字列テンプレート、if-else式などが簡潔な コードの実現に寄与 ● クラスはメソッドとプロパティ、プライマリコンストラクタを持つこ とができる ● 既存の型に対してメソッドを追加するような拡張関数 ● NotNullとNullableを厳格に区別してNull安全に ● データを表現するクラスはデータクラスにすると便利