B-Teck!

お仕事からゲームまで幅広く

【Kotlin】KotlinのReified type parametersについて

前置き

【Kotlin】Kotlin+JacksonでJSONをparseする - B-Teck! のparseJSONがなぜ型情報を使えるのか
会社でJavaを書いている人にこの話をしたところ驚かれたので。

Genericsとtype erasure

JVMにおけるジェネリクスはJava1.4以前のバイナリとの仕様互換のため、
コンパイル時には型情報が削除され、実行時にはその型情報についてアクセスすることができない。
Javaではよく知られた仕様であり、Kotlinでも同様の動作をしている。

イレイジャについてより詳しく知りたければ下記の記事などを参照
贖罪のイレイジャ - プログラマーの脳みそ

inline関数とReified type parameters

ただKotlinでは、関数をinlineで宣言した上で、型パラメータをreifiedとすることで、
実行時に型引数を参照するような形で書くことができる。

inline関数

inline修飾子を付けた関数を、inline関数と呼ぶ。
この修飾子のついた関数は、コンパイル時に呼び出し元にコードとして展開され、
関数呼び出しの形ではなくなる。C言語のマクロに似ているらしい。
関数呼び出しがなくなることで処理速度の向上が見込めるが、
コードとして展開されるためバイナリのサイズは大きくなる。

Reified type parameters

inlineのジェネリクス関数の型にreifiedキーワードを用いることで、
実行時に扱っている型の情報を扱うことができるようになる。
何が嬉しいかというと、与えられたTの型によってJSONをパースするclassを切り替えたいとかのときに、
外から型を渡してあげることができたり、
ジェネリクスを扱う関数の中でTでキャストとか、is Tとかしたりできる。
Inline Functions and Reified Type Parameters - Kotlin Programming Language
より詳細な仕様は下記
kotlin/reified-type-parameters.md at master · JetBrains/kotlin · GitHub

Javaからは呼べない

JavaからKotlinのinline関数を呼び出した場合、Javaのコンパイラではstatic関数を呼び出すようにコンパイルされる。
Call Kotlin inline function from Java - Stack Overflow
reifiedはコードがインライン展開されていることを前提としているため、エラーとなってしまう(らしい) How can I call Kotlin methods with reified generics from Java? - Stack Overflow

まとめ

  • Kotlinではinline関数とreifiedを組み合わせて利用することで、ジェネリクスでも型情報を扱える
  • JavaからReified type parametersを利用したメソッドを呼び出した場合、エラーとなってしまう

【JavaScript/Vue.js】Vue.jsとVuetifyを使ってTodoリストを作ってみた

f:id:beatdjam:20190629195739p:plain

ちょっと会社でVueを触る機会があったので、勉強がてらTodoリストを作ってみました。
リポジトリと動作サンプルは下記
GitHub - beatdjam/training_vue-cli-todo
サンプルページ

やったこと

vue-cliインストール

$ npm install -g @vue/cli

プロジェクト作成

$ vue create my-project

Vuetify導入

$ vue add vuetify

ファイル整理

Todoを作り始めるにあたっていらないファイルを削除
[remove]Unnecessary files removed · beatdjam/training_vue-cli-todo@3fb851f · GitHub

完成イメージを考える

適当にUIイメージをメモに書き出すなど

必要なComponentをVuetifyのサイトで検索して配置

とりあえず今回はこの辺のドキュメントをサラッと眺めました

  • v-toolbar
  • v-form
  • v-text-field
  • v-btn
  • v-date-picker
  • v-list
  • v-checkbox
  • v-icon

Quick Start — Vuetify.js

追加・削除の処理などを実装

コンポーネントに頼ったので、ロジック的には追加・削除しか書かずに実装できました。

Github Pagesに公開

下記のページを参考に設定
https://www.shookuro.com/entry/2019/02/02/174655

感想

Vue.jsの機能とVuetifyのコンポーネント群を利用することで、
曖昧な理解でも簡単にそれなりのアプリケーションを構築することができてしまいました。
小さめのプロダクトをスモールスタートするときに使うには良いと思います。
ただ、jQuery等と同様に、裏側の処理等を知らないまま負債を積み上げてしまうような気がしました。
最近 Vue.js入門 基礎から実践アプリケーション開発まで を購入したので、
読み進めながらもっと勉強していきたいと思います。

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

  • 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/09/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

【Kotlin】data classにJavaから呼び出せるBuilderを用意する

はじめに

Kotlinには名前付き引数を利用することができるので、
コンストラクタに渡す引数をわかりやすく記述することができます。

Person(
  name = "taro",
  age = 20
)

しかし、JavaとKotlinが混在している場合は、Javaからは名前付き引数の仕組みを利用できません。
そうした場合には、KotlinのclassにBuilderを定義することで、
Java、Kotlin両方から扱いやすいclassにすることができます。

data classにBuilderを定義した例

以下の例はKotlinのdata classにBuilderを定義したものです。

data class Person(
    val name : String,
    val age : Int
) {
    class Builder(
        private var name : String? = null,
        private var age : Int? = null
    ) {
        fun name(name : String) = this.also { it.name = name }
        fun age(age : Int) = this.also { it.age = age }
        fun build() = Person(this.name!!, this.age!!)
    }
    companion object {
        @JvmStatic
        fun builder() = Builder()
    }
}

Kotlin・Javaからの呼び出し方

このdata classは、Kotlinからは冒頭と同様に下記の形でインスタンスを作成できますし、

Person(
  name = "taro",
  age = 20
)

Javaからはこのように呼ぶことができます。

Person.builder()
  .name("taro")
  .age(20)
  .build();

より良い書き方があるかもしれないので、ご存知の方はコメントなどでお知らせください。