1. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
は じ め て の K o t l i n
虎の穴 開発室
上田昌寛
2. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
この講義の対象者
• Kotlin言語を基礎から学びたい
• Java言語はプログラミングしたことがある
• 最近のモダンな言語を学びたい
1
3. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
この講義のゴール
• Kotlin言語の基礎的な言語仕様を理解する
• 自分でKotlin言語でクラスや関数を実装する
• Javaと比較して簡潔に書ける事を体験
2
4. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎編の目次
1. ハンズオンの準備
2. Kotlin 概要説明
3. 基礎構文の説明
4. コレクション(List)の説明
5. 拡張関数の説明
6. クラスの説明(getter/setter)
7. パッケージの説明
8. ラムダ式
9. 簡単なWebアプリサンプルの紹介
3
5. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
自己紹介
上田昌寛(Ueda Masahiro)
開発室所属
• 2017年5月に入社
とらのあなKEEPER,Fantia,
とらのあなクラフトの開発,保守メンテ
• Java開発は前職でのAndroidアプリ開発から
• ほか使える言語C,Ruby,JavaScript
あとほんの少しScheme
4
6. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Kotlinとは
JetBrains社の研究所で生まれた言語
マルチパラダイム言語である
Java言語よりも簡潔・安全に開発できるよう設計
Javaとの相互運用を目的に設計
型推論でスマートな記述が可能
Null許容型で型安全にコーディングが可能
5
7. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
さっそく動かしてみましょう
6
実行ボタン
package sample
fun main(args: Array<String>) {
println("Hello World!")
}
実行してみましょう
8. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
さっそく動かしてみましょう
IntelliJにもREPLが使えます。
「Tools」→ 「Kotlin」→「Kotlin REPL」
7
Command + Enterキーで実行
9. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
さっそく動かしてみましょう
Javaコードに変換してみましょう
「Tools」→ 「Kotlin」
→「Show Kotlin Bytecode」
8
バイトコード化
10. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
さっそく動かしてみましょう
「Decompile」ボタンを押してJavaコード化
9
クリック
11. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Hello World について
10
package sample
fun main(args: Array<String>) {
println("Hello World!")
}
• classを作る必要がない
– class定義は後ほど
• 関数定義はfunキーワード
– 関数定義は後ほど
• package で管理します
– 詳細は後ほど
12. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 - 変数の宣言
val a :Int = 5
11
型を省略することが出来る
キーワード「val」は変更不可を表し初期値以降変
更ができません。
val b = “Tora”
b = “yume” // 代入出来ない!
val a = 5
変数宣言の為のキーワード
13. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 - 変数の宣言
var c = 5
c = 10
12
var b :String
// 処理
b = ”Toranoana”
キーワード「var」で変更可能な変数として宣言
val と違い、初期値を省略できます。
ただし省略した場合は「型」の記載が必須
初期値を代入する時、「型推論」が働き、
型を明示する必要はありません。
14. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null非許容型
13
var name :String = null
コンパイルエラーになる
以下のように、nullを代入することは出来ません。
これは 変数「name」が null にならないことを意
味します。
15. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null許容型
null を保持できる変数を宣言したい場合
以下のような宣言になります。
14
var name :String? = null
型の後ろに「?」を付ける
コンパイルエラーにならない
16. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null許容型
nullがあり得ない変数である
15
nullチェックがコードが不要になる!
17. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null許容型
var name :String? = null
// (中略)
if ( name != null ) {
length = name.length()
} else {
length = 0
}
16
var name :String = “”
// (中略)
length = name.length()
Nullチェックが冗長さを生む
null非許容型を優先的に使うことで、
コードがスマートになる!
18. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null許容型 – 安全呼び出し
var name :String? = null
// 処理中略
var value = name?.length()
• nameがnullだった場合
– valueにはnullが入る(Javaだとヌルポ)
• nameがnullではない場合
– valueにはname.length()の値が入る
17
「?.」を付けることで安全呼び出しになる
19. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Null許容型 – エルビス演算子
var name :String? = null
// 処理中略
var value = name?.length() ?: 0
• nameがnullだった場合
– valueには0が入る
• nameがnullではない場合
– valueにはname.length()の値が入る
18
「?:」よりも右にnullだった場合の戻り値を指定できます
20. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
コレクション
• 変更可能なList
val mutableList = mutableListOf(1,3,5,7,11)
• 読み取り専用List
val list = listOf(2,4,6,8)
list.add(10)
19
addメソッドなどによる要素の追加などできない
21. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 if 式
20
Kotlinでのifは文ではなく、式として扱います。
if ( [条件文] ) {
// 処理
} else if {
// 処理
} else {
// 処理
}
22. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 if 式
21
文ではなく式なので値として、計算、
代入が可能
answer = if ( a > b ) a else b
Ruby言語の if 修飾子
> answer = a if a > b
TOPIC
23. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 while 文
22
whileはJavaとほぼおなじ書き方で、「文」です。
while( [条件文] ) {
// 処理
}
do {
// 処理
} while ( [条件文] )
24. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
基礎構文 for文
• Java言語やC言語に見られる以下のようなコードは書け
ません。
for (int i = 0; i < 10; i++) {
// 処理
}
23
• Kotlinの場合、範囲を扱うRangeやListを使います。
for ( i in 0..10 ) {
// 処理
}
範囲を表す Range オブジェクト
25. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
練習 FizzBuzz (5〜10分)
• 1〜50 の値を標準出力するFizzBuzz.ktを作りま
しょう。ただし、以下の条件を設けること。
3の倍数の場合は”Fizz”を出力
5の倍数の場合は”Buzz”を出力
15の倍数の場合は”FizzBuzz”を出力
それ以外はその数を出力
24
26. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
練習 FizzBuzz 回答例
fun main(args: Array<String>) {
for (number in 1..100) {
if (number % 15 == 0) {
println("FizzBuzz")
} else if (number % 5 == 0) {
println("Buzz")
} else if (number % 3 == 0) {
println("Fizz")
} else {
println(number)
}
}
}
25
27. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
関数宣言
fun plus( a :Int, b :Int ): Int {
return a + b
}
26
funをキーワードとし、以下のように書きます。
処理
引数 戻り値の型名前
命名規約については基本的に Javaに従う方針
キャメルケース(アンダースコアーは避ける)
リンク: 公式ドキュメント
TOPIC
28. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
関数宣言
fun plus( a :Int, b :Int ): Int = a + b
27
関数処理が一つの式である場合、
以下のように省略することが出来ます。
処理
引数 戻り値の型名前
29. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
関数宣言
fun absolute(value :Int): Int =
if (value >= 0) value else -value
28
if も式なので
以下のように書くことが出来ます。
処理
30. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
classの定義とインスタンス生成
class Book {
var title: String = “”
}
29
プロパティ定義
Book というクラスを定義
Book のインスタンスを生成
val book = Book()
book.title = “ToraBook”
new キーワードが不要
31. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
コンストラクタ
class Book(var title: String)
30
コンストラクタの引数
Book クラスのコンストラクタを定義
Book のインスタンスを生成
val book = Book(“ToraBook”)
インスタンス生成
32. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
クラス内のアクセス修飾子
class Book(val title: String, val value: Double)
{
fun taxValue() :Double {
return value * 0.08
}
}
31
Class内で定義したプロパティやメソッドはデフォ
ルトでpublic です。
public は省略可能
33. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
getter は?
32
class Book {
var title: String = ""
get() = "[${field}]"
}
バッキングフィールド
val book = Book()
book.title = “ToraBook”
println(book.title) // “[ToraBook]”と表示
34. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
setter は?
33
class Book {
var title: String = ""
set(value) {
field = "title: ${value}"
}
}
val book = Book()
book.title = “ToraBook”
println(book.title) // “title: ToraBook”と表示
文字列”title: “を先頭に付与
35. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
data class
data class Book (val id: Int,val title: String)
34
キーワード「data」を付ける
複雑な挙動は必要とせず、ただデータだけを格納
したい場合などに使用
val book = Book()
book.title = “ToraBook”
new キーワードが不要
36. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
data class で簡単にデータ比較
data class Book (val id: Int,val title: String)
val doujin1 = Book(111, “yume”)
val doujin2 = Book(111, “yume”)
doujin1 == doujin2 // true
35
内部のデータ比較ができる
参照値の比較ではなく、保持するデータの比較が
できる
37. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
パッケージについて
• Javaではclass単位でパッケージの管理ができま
したが、Kotlinでは関数でも変数でも可能です。
36
package utilpkg
val utilValue = 123
fun utilFunc() {
println("Util Func call")
}
package sample
fun main(args: Array<String>) {
println(utilpkg.utilFunc())
println(utilpkg.utilValue)
}
Util.kt Main.kt
123
“Util Func call”
38. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
練習 クラスの実装(5〜10分)
買い物かご、Cartクラスを実装してみましょう。
【実装】
• 支払い金額の合計を保持するプロパティ
• 支払い金額を追加するaddValueメソッド
37
【呼び出し側】
fun main(args: Array<String>) {
val cart = Cart()
cart.addValue(1000)
cart.addValue(500)
// 支払金額
println( "支払い合計:" + cart.payment)
}
39. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
練習 クラスの実装 – 回答例
class Cart(var payment: Int = 0) {
fun addValue(value :Int) {
payment += value
}
}
38
40. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
拡張関数とは
既存のクラスに新しいメソッドを追加したような
記述でプロパティを扱うことが出来る関数
39
41. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
拡張関数 – コードで書くと
fun String.toNumber(): Int {
return Integer.parseInt( this )
}
40
レシーバー型
レシーバーオブジェクト
“13”.toNumber() + 10 // 23
拡張関数の呼び出し
42. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
ラムダ式
ラムダ式の構文
{x: Int, y: Int -> if (x > y) x else y}
• 処理部は複数行記載可能
• 戻り値は return ではなく最終行の評価値
41
引数 処理
43. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
高階関数
Kotlinのラムダ式は一級オブジェクト
• ラムダ式を変数に代入できる
• ラムダ式を関数の引数として渡すことが出来る
– 関数型が存在する
42
詳細は次のスライドで
44. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
高階関数 - 関数型
{x: Double -> x * 1.08 }
( Double ) -> Double
fun tax(value :Double, calc:(Double) -> Double) :Double {
return calc(value)
}
tax(100.0, { x -> x * 1.08 }) // 108.0
43
関数型
引数 戻り値
45. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
本講義のまとめ
• ここで紹介した内容はKotlinの一部
– 便利なWhen構文
– レシーバー付きラムダ
– コレクション操作
– 演算子のオーバーライド etc…
• Javaの代替ではなく共存
• Null安全な型でスマートなコードを実現
44
46. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル
簡単なWebアプリを紹介します
45
47. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル
アニメ情報を返すAPIを呼んで、
シーズン毎のアニメ一覧を表示させる
46
48. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル
アニメ情報取得API
http://api.moemoe.tokyo/anime/v1/master/2
018/1
(今期のアニメ一覧がJSONで取得できる)
47
49. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル
2018/1の場合だと以下のようなJSONで取得でき
ます。
48
1つのアニメ情報
アニメ情報オブジェクトを配列で返す
50. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル
以下のGitHubにサンプルを用意しました。
https://github.com/toranoana/animelist-
kotlin.git
49
51. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル – 構成
サンプルで使用しているライブラリ
• Spark Framework (軽量なWebフレームワーク)
• OkHttp (HTTP通信クライアント)
• Jackson (JSONパーサー)
50
Apache Sparkではありません
52. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル – 構成
• プロジェクト内の「build.gradle」にライブラ
リの依存を定義しています。
• IntelliJから実行しすることでサーバーが立ち上
がり以下のURLで参照出来ます。
http://localhost:4567/list
51
53. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル – 構成
アニメ情報を取得するための data class
52
data class AnimeInfo(
var title_short2: String,
var twitter_account: String,
var public_url: String,
var title_short1: String,
var sex: Int,
var twitter_hash_tag: String,
var id: Int,
var sequel: Int,
var created_at: String,
var city_name: String,
var cours_id: String,
var title: String,
var city_code: Int,
var title_short3: String,
var updated_at: String)
model.kt
54. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
Webアプリのサンプル – 構成
アニメ情報を取得するための処理
Thymeleafの変数に取得したデータを格納して、
アニメタイトルをブラウザ上で表示させています。
53
animeList.kt
JSONをパースし、AnimeInfoのリストが格納されます
55. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
サンプルの取得方法
【git cloneの場合】
$ git clone https://github.com/toranoana/animelist-kotlin.git
【zip でダウンロード】
1. ブラウザで以下を開く
https://github.com/toranoana/animelist-kotlin
2. 「Download ZIP」をクリックしてダウンロード
54
56. Copyright (C) 2018 Toranoana Inc. All Rights Reserved.
サンプルの取得方法
• IntelliJ でプロジェクトを開く
• 「open」をクリックして、clone もしくはダウ
ンロードしたフォルダを選択します。
55