2015年12月 1日

Android

次世代言語Kotlinを使ったAndroid開発とヤフーの新技術との向き合い方

  • このエントリーをはてなブックマークに追加

Yahoo! JAPAN Tech Advent Calendar 2015の1日目の記事です。一覧はこちら

こんにちは、ヤフーでAndroidアプリ開発をしている松田(@shoma2da)です。
今年もやってきたヤフーのアドベントカレンダー、僭越ながらトップバッターを務めさせていただきます!

初日となる今日は最近話題になっているKotlin(ことりん)という言語を使ったAndroidアプリ開発と、これに関連してヤフーが新技術にどのように向き合っているかについて書いていきます。

Kotlinとは

Kotlinは2011年頃に登場した言語で、開発元はJetBrainsです。
JetBrainsといえばAndroid StudioのベースであるIntelliJを開発している企業でもあります。
ソースコードはOSSとして公開されておりGitHubから確認できます。

Kotlinはオブジェクト指向をベースにしていますが、そのほかさまざまなスクリプト言語や関数型言語の影響を受けた言語仕様を持っています。

なぜ今Kotlinが注目されているのか

無数にあるプログラミング言語の中でなぜKotlinなのでしょうか。
Kotlinに着目したいくつかの理由について説明していきます。

Javaとの親和性の高さ

KotlinはプラットフォームとしてJavaを選択しています。
これはJavaで書いた場合と同様にKotlinのソースコード(*.kt)をコンパイルするとクラスファイル(*.class)ファイルが作成され、JavaVM上で動作させられることを意味します。
(厳密にはAndroidの実行環境はDalvikVMやARTです。そのためクラスファイルの他に生成されるファイルやコンパイル周りの処理の違いはありますが、基本的にはJavaプラットフォームにおける利点はそのまま享受できます)

これによってソースコードがKotlinであろうがJavaであろうがそれらに記述したクラスやメソッドは相互に利用可能(JavaからKotlinを利用することもその逆も可能)となります。
そのため既存のJavaからの移行に際して全てをKotlinに書き換える必要はありません。
対応できる部分から部分的に対応していくなど状況に応じた選択をしていくことができます。

JavaとKotlinは相互に利用可能

まもなく正式版公開

Kotlinは長らくメジャーバージョン(1.x.x)が出ていない状況でしたが、10月末に1.0.0-Candidate版、11月中にBetaとBeta2版が立て続けにリリースされています。

公開されているGitHubを見るとよくわかりますがKotlinは非常に開発が活発な状況が続いています。
そのためおそらく数週間から数カ月以内には正式な1.0.0版がリリースされることが予想できます。

正式版が出るということは言語としての安定性もある程度は担保されることから利用を開始するタイミングとして判断しても良いでしょう。

言語仕様

Kotlinの言語仕様を語る際に「簡潔」や「安全」といった特徴がよく挙げられます。
型推論や各種の省略記法、nullに対する安全性担保や不変(Immutable)のサポートといったさまざまな言語仕様がこれらを実現しています。
抽象的ではありますが「カタすぎずゆるすぎず、かゆいところによく手の届く言語」というのが私個人のKotlinに対する感想です。

それではKotlinの具体的な言語仕様をいくつか確認していきましょう。
Javaを使う場合と比べての利点についても確認できればと思います。
本記事では概要のみ触れていきますので詳しく知りたい場合は公式ドキュメントなどをご覧ください。

ラムダ式

ラムダ式はJava 8からは採用されましたが、Androidでは2015年11月時点でも標準では使用できません。(Retrolambdaなどのバックポートツールを使う必要があります)
Kotlinでは標準の言語仕様としてラムダ式が存在しています。

//java
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //do button action.
    }
});

//kotlin
findViewById(R.id.button).setOnClickListener({ v ->
    /* do action */
})

Null Safety

NullPointerExceptionはプログラムを書く上では絶対に避けられない問題でしょう。

KotlinではNullに対する対応として型による解決を試みています。
型でnullを参照し得るかどうかを扱うことによってコンパイル時点で検証が可能になります。
そのため実行時に(最悪の場合Google Playにリリースしてから!)想定外のnullが来てクラッシュする、といった問題を回避できます。

具体的な記述方法としてはnullを許容する場合のみ型の最後に?を付けるといったものです。
簡単な例を示します。

var a: String = "abc"
a = null //コンパイルエラー! Null can not be a value of a non-null type kotlin.String

var b: String? = "ABC"
b = null //コンパイルエラーにならない

?付きの型から値を取り出したりメソッドを呼び出す場合はifなどで条件判定してから扱うか?!!といった記号を使用します。
(このうち!!はNull Safetyの言語仕様のメリットを無くしてしまうものですので基本的には使用しないほうがよいでしょう)

var str:String? = "abc"

val length1 = str.length //コンパイルエラー!Nullableな型はそのままメソッド呼び出しできない
if (str != null) {
    val length2 = str.length //コンパイルエラーにならない
}
val length3 = str?.length //コンパイルエラーにも実行時エラーにもならない。strがnullの場合はlengthもnullになる
val length4 = str!!.length //コンパイルエラーにならないが実行時にNullPointerExceptionの可能性がある

Javaは型でnullに関する情報を扱えないため、KotlinとJavaを相互に使用する場合は返却値などがnullになりえるかどうか注意する必要があります。
こうした注意点も加味しながらうまくこのNull Safetyを扱えばみなさんのAndroidアプリからNullPointerExceptionを一掃できるでしょう。
ちなみにiOS開発に採用されているSwiftでもほぼ同様の言語仕様が取り入れられています。

Extension

Kotlinでは継承なしでクラスにメソッドを増やす(拡張する)ことができます。
例としてListの要素を交換するswapメソッドを拡張する場合は以下のように記述します。
この機能はメソッドの定義箇所が散らばってしまって管理が難しくなる懸念もありますが、ここぞというときに使用するのには非常に便利でしょう。

fun MutableList<Int>.swap(index1: Int, index2: Int) {
  val tmp = this[index1]
  this[index1] = this[index2]
  this[index2] = tmp
}

//別の箇所
list.swap(0, 1) //listの0番目と1番目を入れ替える

このソースコードに合わせた余談ですが、Kotlinにはオブジェクトの状態が変更可能であるMutableと一度生成したら状態を一切変更できないImmutableとを明確に分けて命名やコーディングされている箇所が多く出てきます。
一度その点についても整理しておくと良いでしょう。

クラスの定義とコンストラクタ

Kotlinではクラスの定義に合わせてコンストラクタを記述できます。
これによってソースコードが短くなることや、valvarというキーワードを使って簡潔にread-onlyなどアクセス制限の設定ができます。

下記のJavaとKotlinで書かれた2つのEmployeeクラスはほとんど同様の仕様を持っています。

//java
public class Employee {
    private String mId;
    private String mName;
    public Employee(String id, String name) {
        mId = id;
        mName = name;
    }
    public String getId() {
        return mId;
    }
    public String getName() {
        return mName;
    }
}

//kotlin
public class Employee(val id:String, val name:String)

上記のように2つの言語を比べるとKotlinがいかに簡潔に記述できるかがわかるかと思います。

Android開発のための初期設定

ここまででいくつかの言語仕様をご紹介してきましたが、KotlinをAndroid開発で使用するためにはどうしたら良いでしょうか。

標準的な方法としてはAndroid StudioにJetBrains公式のKotlinプラグインを導入する方法があります。
Kotlin公式サイトに手順の記載がありますので詳細についてはこちらをご覧ください。
(拙作ですがSlideShareに日本語資料もあります)

公式資料中には既存のAndroidプロジェクトとの併用についての記載がないですが、下記のようにbuild.gradleに一行足すだけでjavaディレクトリとkotlinディレクトリ両方を使用できます。
今すぐに手元のプロジェクトにKotlinを導入したい場合はプラグインの導入に加えてこのような対応をすると良いでしょう。

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        main.java.srcDirs += 'src/main/java' //この行を追加
    }

ヤフーのアプリ開発における新技術導入

Kotlinの言語仕様や導入方法について触れてきましたが、ヤフーでの実際のアプリ開発現場でKotlinのような新技術導入がどのような環境の中で進められているかについてご紹介します。

ヤフーではサービス提供品質やUI/UXなどを担保できている前提の中で、ライブラリやOSS選定・開発の進め方について各アプリである程度自由に選択することができます。

今回ご紹介したKotlinについても社内のいくつかのアプリでは導入が検討されています。
メリット・デメリット(移行や学習のコストと得られるメリット、その技術の安定性や情報量、最悪の場合にはすぐに取り除けるかなど)や各アプリチームのスキルセット・案件状況といったことが勘案されています。

当然のことながら正解がある問題ではないので各プロダクトで実際にKotlinの導入を進めるかどうかの判断は今後異なってくるでしょう。

知識共有の機会

各アプリに裁量が委ねられていることによってチームごとに状況に応じた柔軟な対応ができる一方、そうした状況だけが続けば各アプリ間の知識や技術力の格差が発生しかねません。

ヤフーでは高い専門性を有する「黒帯」という役割の方が社内全体に向けて情報共有を行ったり、有志によるLT(ライトニングトーク)会や勉強会が頻繁に行われています。
また、GitHub Enterpriseで社内のソースコード管理が行われているため社員であれば誰でも各アプリのソースコードを確認できます。

ヤフーではこうしたちょっとした活動や環境の積み重ねがあることによって、極端な知識や技術力の格差はほとんどなしに各アプリが開発を進められているように思います。

楽しくワイルドに仕事をする

本記事ではKotlinという言語の紹介やヤフーでの新技術への向き合い方についてまとめてきました。

数年前にヤフー経営陣が新体制になって以来「迷ったらワイルドな方を選べ」といったメッセージが社内で幾度となく繰り返されています。
このメッセージは今現在も開発現場で当たり前に話されるメッセージとなっており、たとえ社内で利用実績のない技術であっても将来性や選択理由を明確にすることでチャレンジできるような雰囲気の中で仕事ができています。
こうした雰囲気はヤフーで働く上での一つの特徴ではないかと思いますし、とても楽しく良いことだと思っています。

それではこの辺で終了したいと思います。みなさま良いお年を!

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加