はじめてのKotlinハンズオン #DroidKaigi

14c9795d267f5b85abb98ca5e8780646?s=47 Taro Nagasawa
February 09, 2018

はじめてのKotlinハンズオン #DroidKaigi

14c9795d267f5b85abb98ca5e8780646?s=128

Taro Nagasawa

February 09, 2018
Tweet

Transcript

  1. はじめての Kotlin ハンズオン

  2. もくじ 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5.

    クラスとオブジェクト 6. Null安全
  3. このハンズオンで... Kotlinって良い言語って聞くけど 何が良いのか どうやって始めるのか どうやって書くのか 次のステップは?

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

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

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

    6. Null安全
  7. Kotlinとは? • 静的型付けオブジェクト指向言語 • ターゲット: Java仮想マシン、Android、JavaScript、 ネイティブ • 開発元: JetBrains

    • 2011年7月発表、2016年2月正式リリース • Apache License ver 2.0 Better Java
  8. Kotlinの特徴 簡単 文法、コードの見た目がわかりや すい。学習コストが低そう 安全 型安全、Null安全 Android Googleのお墨付き! Interop KotlinからJavaコードを、Javaから

    Kotlinコードを相互に呼び出せる
  9. 簡単!Better Java ユーザを表現するUserクラス  ・name: 名前  ・id: 識別キー。nullの可能性あり こんなクラスが 欲しいな!

  10. 簡単!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で書くと...
  11. 簡単!Better Java data class User(val name: String, val id: Long?)

    サイコー以外の 言葉が見つから ない Kotlinで書くと...
  12. 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト

    6. Null安全
  13. Try Kotlin • http://try.kotl.in • ブラウザ上で試せる開発環境

  14. Hello World package sample fun main(args: Array<String>) { println("Hello, world!")

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

    4. URLを共有する
  16. 解答例は公開済み! https://goo.gl/QgCVUM

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

    6. Null安全
  18. 基本的にはJavaにそっくり fun main(args: Array<String>) { 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 }
  19. 変数宣言のための2つのキーワード • val … 再代入NGな変数を宣言する • var … 再代入OKな変数を宣言する fun

    main(args: Array<String>) { var count: Int = 0 count++ println(count++) // 1 }
  20. 推論できるところは大抵 型を省略できる • 関数の戻り値の型 • ラムダ式の引数の型 • 型引数 val hoge

    = "I love Kotlin" val fuga = hoge.reversed() val piyo = fuga.length この他に などが省略可能な場合がある
  21. 文字列リテラルが便利だよ! val name = "おにぎり" val price = 120 println("${name}が3個で${price

    * 3}円です") val html = """<div> <p>Hello, world!</p> </div>""" println(html) 文字列テンプレート raw-string
  22. if-else: Javaとほぼ同じ fun main(args: Array<String>) { if (args.size > 0)

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

    (args.size > 0) args[0] else "名無し" println("こんにちは、${name}さん") }
  24. forループ fun main(args: Array<String>) { val names = listOf("foo", "bar",

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

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

    "baz") for (name in names) { println(name) } } 繰り返し可能なオブジェクトに対して 要素を順に取り出す
  27. レンジ fun main(args: Array<String>) { var sum = 0 for

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

    (i in 1..10) { sum += i } println(sum) // 55 } 「1から10まで」のレンジ(範囲) オブジェクトを生成する
  29. whileループ: Javaとほぼ同じ fun main(args: Array<String>) { var count = 3

    while (count >= 0) { println(count--) } }
  30. [課題] FizzBuzz • 1から100までをプリントする。ただし: ◦ 3で割り切れる数は、その数字の代わりに「Fizz」をプリントする ◦ 5で割り切れる数は、その数字の代わりに「Buzz」をプリントする ◦ 3と5それぞれで割り切れる数は、その数字の代わりに

    「FizzBuzz」をプリントする
  31. [課題] 世界のナベアツ問題 • 1から40までの数をプリントする • 3の倍数の場合「!」を後ろに付ける • いずれかの桁に3を含む数の場合も「!」を付ける 1 2

    3! 4 5 6! 7 8 9! 10 11 12! 13! 14 15! 例
  32. まとめ • リテラルや演算子などはJavaにそっくり • 再代入OKな変数宣言 var、再代入NGな変数宣言 val • 型推論により型の記述を省略可能 •

    文字列リテラルが便利: 文字列テンプレート、raw-string • if-elseは式である • forループは、Javaの拡張for文に似ている • listOf関数により、リストをつくることができる • 範囲を表すレンジオブジェクト (e.g.) 1..5 • whileループは、Javaとほぼ同じ
  33. 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト

    6. Null安全
  34. 関数入門 fun add(a: Int, b: Int): Int { return a

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

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

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

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

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

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

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

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

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

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

    + b } fun main(args: Array<String>) { val sum = add(3, 7) println(sum) // 10 }
  45. 単一式関数 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 型を省略するのは楽だけど 明示した方が読み返したときに わかりやすい!
  46. [課題] いろんな関数をつくって遊ぼう 下記の様な関数を作る。 • 引数として与えられた整数を2乗した数を返す関数square • 引数として与えられた2つの整数のうち、大きい方を返す 関数max • 引数として与えられた整数が偶数の場合にtrueを、それ

    以外の場合にfalseを返す関数isEven • 引数として与えられた整数の階乗を返す関数factorial ◦ 例)4の階乗 = 4 * 3 * 2 * 1 • 引数として与えられた整数に、3が含まれるかどうかを返 す関数containsThree
  47. 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト

    6. Null安全
  48. クラスの定義 class Person(val name: String) val taro: Person = Person("Taro")

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

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

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

    println(taro.name) // Taro プロパティ
  52. メソッドの定義 class Person(val name: String) { fun introduceMyself() { println("I

    am ${name}") } } val taro: Person = Person("Taro") taro.introduceMyself() // I am Taro
  53. [課題] クラスの定義 • クラス名 IntPair • 2つのプロパティを持つ ◦ first: Int

    ◦ second: Int • 3つのメソッドを持つ ◦ sum: firstとsecondの和を返す ◦ max: firstとsecondのうち大きい方を返す ◦ swap: firstとsecondが逆になったIntPairオブジェクトを返す
  54. クラスが実装すべき便利メソッド class IntPiar(val first: Int, val second: Int) { //

    省略 override fun toString(): String = "IntPair(first=$first, second=$second)" } • toStringメソッド • equals/hashCode   → 機械的に導き出すことができる
  55. データクラス data class IntPiar(val first: Int, val second: Int) {

    // 省略 } fun main(args: Array<String>) { val oneAndTwo = IntPair(1, 2) println(oneAndTwo) // IntPair(first=1, second=2) println(oneAndTwo == IntPair(1, 2)) // true println(oneAndTwo === IntPair(1, 2)) // false }
  56. 拡張関数 fun String.hello() { println("Hello, ${this}!") } val name =

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

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

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

    "world" name.hello() // Hello, world! メソッドのように呼び出せる
  60. [課題] 拡張関数との出会い • 拡張関数 meets ◦ Intに対する拡張関数 ◦ Int型の引数を1つ取る ◦

    自身がfirstに、引数がsecondになるIntPairオブジェクトを返す
  61. まとめ • クラスやオブジェクト、インスタンスの考え方はJavaとほぼ同じ • クラスはプライマリコンストラクタを持つ • クラスはメソッドを持つことができる • クラスはプロパティを持つことができる •

    プライマリコンストラクタの引数を、そのままプロパティとして宣 言することができる • インスタンス生成の際にnewのようなキーワードは不要 • 既存のクラスにメソッドを追加するような「拡張関数」というもの を定義できる
  62. 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト

    6. Null安全
  63. Null安全 • nullの可能性のあるものと、そうでないものを厳格に 区別することでケアレスミスを防ぐ • nullの可能性のない型(NotNull) • nullの可能性のある型(Nullable) ?をつけて表現 val

    a: Int = null // コンパイルエラー val b: Int? = null // OK b.toString() // コンパイルエラー
  64. Nullableの扱いは、とことん慎重に val s: String? = getString() s.length // コンパイルエラー これを許してしまうと

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

  66. 安全呼び出し s?.length if (s != null) s.length else null 同じ

    if-elseは式 (評価されて値になる) foo?.bar()?.baz()?.qux() メソッドチェーンで役立つ
  67. [課題] nullを許容するプロパティ • IntPairクラスを元にNulltableIntPiarを定義する ◦ プロパティfirstとsecondがnullを許容する ◦ 各メソッドの戻り値はnullを許容しない ◦ そのとき、nullの値はゼロと見なす

    ▪ (e.g.) first=5, second=nullのとき sum()は5を返す
  68. 1. Kotlinって何だ!? 2. 開発環境の準備 3. 基本的な文法 4. 関数に挑戦 5. クラスとオブジェクト

    6. Null安全 7. おまけ
  69. AndroidでKotlinを始める チェックを入れるだけ

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

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

    機能は言及されていない。
  72. もっと課題やりたいなら Kotlin Koans

  73. 今日登場しなかったキーワード • インタフェース • 抽象クラス • ラムダ式 • 委譲プロパティ •

    シールドクラス • 列挙型 • ジェネリクス • コルーチン • クラス委譲 • 演算子オーバロード など...
  74. 本日のまとめ • KotlinはBetter Java(とはいえJSやNativeも対象) • Kotlinの特徴は、簡単・安全・Android対応・Javaとの親和性 • Javaと似ている文法も多くある • 強力な型推論、文字列テンプレート、if-else式などが簡潔な

    コードの実現に寄与 • クラスはメソッドとプロパティ、プライマリコンストラクタを持つこ とができる • 既存の型に対してメソッドを追加するような拡張関数 • NotNullとNullableを厳格に区別してNull安全に • データを表現するクラスはデータクラスにすると便利