ほのぼのしたエンジニアのブログ

触った技術についてまとめていくブログです。

Kotlin:基本構文

どうもShZgZです。

 

Kotlinをちょっとちゃんとやってみようかと思い、

とりあえずOfficialのReferenceを読んでいきます。

kotlinlang.org

とりあえず原文で読んでいってよく分からないところは日本語版を参考にしていこうかと思います。

基本的にはJavaを知っていて、JavaとKotlinでどう変わったかを確認していく感じなりますが悪しからず。

 

パッケージ定義

パッケージの定義はJava同様一番上です。セミコロンが無いことを除いては変わり無しですね。

package my.demo

import java.util.*

 

 関数定義

関数はかなり変わったというか別物です。

形としてはこんな感じ、

fun 関数名(引数名: 引数の型, ・・・): 返り値の型{

    (処理内容)

    return 返り値

}

返り値の型とreturnを省略して

fun 関数名(引数名: 引数の型, ・・・) = 返り値

こんな風にも書けます。関数型の言語でよくある感じの書き方になってきてるように感じます。実際にはこんな感じです。

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun sum(a: Int, b: Int) = a + b

因みにVoidはKotlinではUnitという型になりました。

 

ローカル変数定義

ローカル変数はvalで定数、varで変数を表すようになりました。

val a: Int = 1
val b = 2
val c: Int
c = 3

var x: Int = 3

x += 1

 

コメント

コメントはJavaから変化無し

// 1行の場合はスラッシュ2つ

/*

複数行の場合は"/* */"でくくる

*/

 

文字テンプレートの使用

文字テンプレートとは

var a = 3

var str = "a is $a" // a is 3

str = "a + 3 is ${a + 3} // a + 3 is 5

 こんな感じで、"$"(ドルマーク)をつけると

文字列の中で、"$"の後の式を評価した値で置換してくれるってやつ

JavaでもString.formatとかでできたけど断然こっちの方が使い易そう。

 

条件式(というかif式)の使用

if文が式になりました。どういうことかと言うと

if (a > b){

    println(a)

} else {

    println(b)

}

今まで通り上記みたいな書き方はできますが、

println(if (a > b) a else b)

こんな感じに、ifは(a > b)を評価した結果がtrueならaを、falseならbを返す式になりました。

Javaでいうif文と3項演算子が1つになった感覚ですかね。

実際、上の2つのソースをコンパイルしたらif文と3項演算子になってました。

 

Null値とNullチェックの使用

KotlinではNullを代入する型と代入しない型で型が変わります。

var a : Int  // nullは入らない(正確にはnullが入るとエラーになります。)

var b : Int? // nullが入る

まぁ"?"をつけるだけです。

実際は、"?"の付いている方はJavaの型と同様で、"?"が付いている方は変数に値が代入される前にnullチェックが行われ、nullの場合はエラーとなるようになります。

この状況で

println(a * b)

などとするとbがnullの可能性があるためエラーとなりますが、

if (b != null){

のようにnullチェックを行うとその中では自動でnullでは無い型へキャストしてくれます。この辺は優秀ですね。Javaじゃいちいち書かなきゃいけなかったチェックは不要になりますね。

 

型チェックと自動キャストの使用

Kotlinさんは賢いことに型チェックを行った変数やプロパティは自動でキャストしてくれます。

fun getStringLength(obj: Any): Int? {
if (obj is String) {
// この括弧内ではobjはStringにキャストされます。
return obj.length
}

// 型チェックの括弧の外なのでここではobjの型はAnyです。
return null
}

上で、Any型はJavaのObject型、ifの中で使われている"is"は"instanceof"です。上の類似で下のような場合も自動的に型がキャストされます。

fun getStringLength(obj: Any): Int? {
if (obj !is String) return null

//この括弧内ではobjはStringにキャストされます。
return obj.length
}

fun getStringLength(obj: Any): Int? {
// "&&"の右側ではobjはString型にキャストされます。
if (obj is String && obj.length > 0) {
return obj.length
}

return null
}

 

forループ

forも書き方が変わりました。

val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}

これは型が省略された感じですね。

Javaなら、

for (String item : items)

とかなんでちょっと短くなったかなって感じです。

val items = listOf("apple", "banana", "kiwi")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}

こっちのインデックスで回してく方はかなり短くなってくれてると思います。

Javaなら、

for (int i = 0; i < items.size(); i++)

ですからね。

 

whileループ

whileは変わり無しですね。

val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}

 

when式

これはJavaでいうところのcaseに近いですが、caseよりも汎用的に使えそうです。

fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}

objの値や型で場合分けしてくれるわけです。複数の条件にしたい場合はカンマでつなげます。(1, 2 -> "One or Two"みたいに)

コンパイルすると中は3項演算子になってました。

 

range

".."を使うことにより範囲を表現することができるようになりました。

if (x in 1..5)  // xが1から5の間にいる場合

for (y in 1..5)  // yは1から5まで1つずつ増えていく

1..5でリストが作られるとかかと思ったんですが、1から5まででforを回してるだけでした。

for (x in 1..10 step 2) {
print(x)
}
for (x in 9 downTo 0 step 3) {
print(x)
}

こんな書き方もできるらしい。

 

collections

forループとwhen式のところでもちょっと触れましたが、collectionsに対して

for (item in items) {
println(item)
}

とか

when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}

とかができて。(whenは引数無しでも大丈夫、中が3項演算子だから条件式にさえなってればいいんですね。)

Java同様ラムダ式もいけると

fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }

ラムダ式は括弧が波括弧に変わりましたが、大体一緒ですね。

 

まとめ

Javaで冗長だと思ってた部分がかなり省略されてる印象です。

省略された感じはしますが、書き方とかどうも学習コストは多少上がった?感じを受けました。元々Javaだからかもしれませんが。

地味に書き方変わってるので、Java8の書き方ができる人ならまぁそんなに苦労することもなさそうに思いますが、ちょっと前のJavaまでしかわからないっていうような人だとちょっと大変かもしれませんね。

ただKotlinの方がコードを書くの自体は楽しそうな気がします。

 

Kotlinを使ってみる

どうもShZgZです。

 

非常に暑く、我が家付近では雨が続いております。

皆さんはいかがお過ごしでしょうか?

 

私は普段Javaエンジニアとして働いていますが、今回はちょっと遅くなりましたが、Kotlinを触ってみようかと思ってます。

 

発表されたのは2011年7月20日とのことですが、その頃は全然知りませんでした。

(そもそもその頃はエンジニアですらありませんでした。)

とはいえ、一昨年くらいからちょいちょい話は聞いていて、今回GoogleさんがkotlinをAndroidの公式言語に追加するということがありました。

 

そのため、ちょっくら触ってみようというわけです。

仕事ではAndroidには全く関わりがありませんが、どうにもJavaとの互換性が高く、Javaよりもコード量が少なくて済むとかなんとか。期待に胸が膨らみます。

 

それではまずはやはりコンパイラを入れるところからやっていきます。

因みにOSはMac OS Xです。

 

インストールですが、MacでHomebrewが入ってれば以下のコマンドで一発です。Homebrew — macOS 用パッケージマネージャー

(因みにですが、ココでブラウザでも実行できます。)

brew install kotlin

 

簡単に文法とか確認するだけならREPLが一番 ♪

ただJava(Version 1.8)にはありません。1.9で追加されるとのことですがまだありません。

しかしKotlinにはREPLがあるということなので以下のコマンドよりREPLを実行

$ kotlinc-jvm

Welcome to Kotlin version 1.0.1 (JRE 1.8.0_60-b27)

Type :help for help, :quit for quit

>>>

それではいつものやつやってみます。

Javaならこんなんですね。

System.out.println("こんにちわ。Javaの世界 !!");

 Kotlinではこんな感じらしいです。

println("こんにちわ。Kotlinの世界!!") 

 お分かりでしょうか?

そうです!!

とうとう標準出力メソッド(println)がデフォルトで使えるようになりました。

もう一つ比較で、

Javaならこんな感じ(注:ソースはイメージです。)

>>> static void test(String str){

... System.out.println("Hello, " + str + "!!");

... }

>>> test("TEST");

 Hello, TEST!!

Kotlinだとこんなのになります。

>>> fun test(str : String){

... println("Hello, $str!!")

... }

>>> test("TEST")

Hello, TEST!!

ここまでのぱっと見の相違点として

・ まずメソッド定義がfunになった。楽しそう!!

・返り値の型がいらんくなった。あえて書くならvoidじゃなくてUnitにするらしい、↓みたいに。

fun test(str : String): Unit {

 ・printlnの中で引数を引用する際に"$引数名"でよくなった。JavaでもString.formatとか使えばいけたけど、これがデフォルトのprintなのは結構助かりそう

・そして、セミコロンがいらん。セミコロンがいらん。

 

とりあえず今回はこれくらいで。

 

 今回は簡単な出力しか試さなかったけど、他の方々が書いてるコードを見るとJavaで書くよりも結構短くなってる印象です。

Javaとの完全互換(Javaで作ったクラスをKotlinで呼べて、Kotlinで作ったクラスをJavaで呼べるとかとか)であることから平行した開発も出来る。Kotlinへの移行を考える際も最悪Javaに戻れるっていう安心感もある。

ただ、今日までエンジニアで出向いた現場でJavaのバージョンは大体1.7以下だった。(今の現場は1.8だけど、1.8で追加されたStreamとか使いまくるとあまり周りから良い顔はされない。まぁ悪い顔されるわけでも無い)

それから考えると、もうすぐJavaは1.9が出て(今のところ2017年9月まで延期っぽい)、Kotlinも盛り上がってきてるけど、SESで出向く先のちょっと大きめの会社の下請けでは採用されるのには結構時間が掛かりそう。

とりあえず個人的にはもうちょっと使ってってみようかと思います。

Rust1日目

どうもShZgZです。

 

普段の仕事ではまず使うことは無いんですが、

最近Rustが熱い

 

全く触ったことの無い言語で

(とは言っても私はJava以外は殆どまともに触ったこと無いんだけど)

とりあえずJava以外も触っていってみようということで触っていきます。

 

ちょっとWikiさんを参照したところ

  • 作った人・・・Graydon Hoare(グレイドン・ホアレさんって読むらしい、最初はホーア論理の人なのかと思ってしまった、恥ずかしい)
  • 特徴・・・安全性、メモリ管理、並列性

そもそも最初にRustに対して興味を持ったのはヴァルちゃんが使ってたからどっかの記事でRustは早い・安全・並行的な部分を押していたからです。

後は、そもそもRustはOCamlで書かれてたらしいんですが、数年前にML系の言語を使っていたためちょっとした懐かしさもあり、Rust使ってみようかなと。是枝くんも綺麗だって言ってたし。

 

とりあえずお勉強するにあたってテキスト的なものはあるかなと探したところバッチリ公式にThe Bookなるものがあると。

日本語版もあるのですが、ちょっと更新が遅いっぽいのと英語だけど結構読み易い感じがするので、英語版のほうを参考にしていきます。まぁこのドキュメント訳していくよって話では無いですが、軽い要約くらいな感じにはなっちゃうかもしれません。悪しからず。

 

全然言語の導入に行けませんでしたが、次回から入っていきます。でわ。

Hello, World

どうも始めましてShZgZと言います。

 

Javaエンジニア3年目になるということで、

そろそろエンジニアらしくはてブDebutしてみようかと思い、始めました。

 

はてブでできることを手探りしつつ書いていこうかと思っているので、

宜しくお願いします。