Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゲーム開発に最適なサーバーサイドKotlin 〜Kotlinの導入と基盤ができるまて...

ゲーム開発に最適なサーバーサイドKotlin 〜Kotlinの導入と基盤ができるまで〜 / CEDEC 2018

CEDEC 2018の発表資料です。

セッションの内容(公式サイトより):
アプリボットではこれまでJavaでサーバーサイドの共通基盤を作成し、ゲームを開発してきました。
その中で昨年、サーバーサイドKotlinに大きな可能性を感じ、今後使用していく言語として選択しました。
現在はJavaで書かれていた基盤もKotlinへと移行し、プロダクトを開発しています。
Android開発の公式言語として話題になっているKotlinですが、なぜサーバーサイドの言語として導入に踏み切ったのか?
その理由とJavaからの移行時に考えるべきポイント、今後の展望などについて事例とともにご紹介します。

https://2018.cedec.cesa.or.jp/session/detail/s5abf865c5ecde

Takehata Naoto

August 24, 2018
Tweet

More Decks by Takehata Naoto

Other Decks in Programming

Transcript

  1. モダンな開発ができる •  コードがシンプル –  型推論 –  String Template –  プロパティ

    –  データクラス –  etc… •  安全 –  Null安全 –  val、var 2-②
  2. 拡張プロパティ 3-③ Kotlinはクラスにプロパティを定義すると、 内部的にアクセサメソッドを⽣成する class User { var name: String

    = "" } val user = User() user.name = "takehata" user.name プロパティの値はアクセサメソッド経由で呼ばれる
  3. public String getMessage() { UserService userService = new UserService(); return

    userService.createMessage(); } val message: String get() { val userService = UserService() return userService.createMessage() } ・get〜という名前の引数なしメソッドが  全てプロパティとして認識されてしまう ・なぜメソッドがプロパティに・・・と⼾惑う Java Kotlin
  4. コンパニオンオブジェクト 3-③ Javaから呼び出そうとすると、Companionというオブジェクトを 経由しなくてはならなくなる @JVMStatic companion object { fun execute()

    { // ・・・
 } } Sample.Companion.execute(); Java Kotlin staticな関数を定義したい時、コンパニオンオブジェクトを使う
  5. SAM変換 3-③ 関数型インターフェースを引数に取るメソッドには、 ラムダ式を渡すことができる public interface FuncJonSample { public Integer

    calc(Integer num1, Integer num2); } public Integer callFuncJon(FuncJonSample funcJon) { return funcJon.calc(1, 2); } 関数型インターフェース(単⼀メソッドのインターフェース) 関数型インターフェースを引数に取るメソッド callFuncJon((Integer num1, Integer num2) -> { return num1 + num2; });
  6. callFuncJon { num1: Int, num2: Int -> num1 + num2

    } ・Kotlinでも同様に呼び出すことができる ・Javaの関数型インターフェースを  Kotlinの関数型として扱ってくれる(これがSAM変換)
  7. ・Kotlin同⼠ではSAM変換が効かず、匿名オブジェクトを  明⽰的に書いて渡さなければならない ・関数によってラムダ式で渡せるものと渡せないものがあり、  なぜ・・・となった fun callFuncJon(funcJon: FuncJonSample): Int? { return

    funcJon.calc(1, 2) } 呼び出されるメソッドもKotlin化してしまうと・・・ callFuncJon(object : FuncJonSample { override fun calc(num1: Int, num2: Int): Int { return num1 + num2 } })
  8. ⾼階関数を使わない場合 3-④ fun callFuncJon(funcJon: FuncJonSample): Int? { return funcJon.calc(1, 2)

    } callFuncJon(object : FuncJonSample { override fun calc(num1: Int, num2: Int): Int { return num1 + num2 } }) 匿名オブジェクトを明⽰的に書いている
  9. ⾼階関数を使う場合 3-④ ・ラムダ式で渡すと、匿名オブジェクトのインスタンスが  呼び出し間で再利⽤される fun callFuncJon(funcJon: (Int, Int) -> Int):

    Int? { return funcJon(1, 2) } callFuncJon { num1: Int, num2: Int -> num1 + num2 } ・ラムダ式を渡して呼び出せるようになる
  10. 通常の⾼階関数のコード 3-④ fun callFuncJon(funcJon: (Int, Int) -> Int): Int? {

    return funcJon(1, 2) } 引数の型に関数リテラルを書いている
  11. Type Ailiasを使ったコード 3-④ typealias FuncJonSample = (Int, Int) -> Int

    fun callFuncJon(funcJon: FuncJonSample): Int? { return funcJon(1, 2) } ・名前を付けることで、関数リテラルの意味が分かりやすくなる ・同じ関数リテラルを複数書く必要がなくなる callFuncJon { num1: Int, num2: Int -> num1 + num2 }
  12. fun createUser(): User? { // ・・・
 } val user =

    createUser() user!!.name JavaはデフォルトでNull許可型なので、変換すると?が付く Nullチェックをしていない変数の呼び出しは、!!を付けて変換される fun createUser(): User { // ・・・
 } val user = createUser() user.name Null不許可型にして、!!も排除する