Kotlin についてメモ（1）

初稿： 2019/7/10
メモ書き中です。 適宜修正・追記していきます。

# Kotlin を始めるにあたって

## Kotlinとは

* 「ことりん」と読む
* Kotlinとは、JVM(Java仮想マシン)で動作する言語。
* JDKが必要
* JVMで動作するようにコンパイルされる。
* 動作するJDKのバージョンに影響を受ける（可能性がある）
* ローカルマシンで動作検証するには、JDKのセットアップが必要


## 参考資料

### Web

最初は存在を知っているくらいでいいと思います。

* [公式サイト](https://kotlinlang.org/)
* [公式サイトのリンク集](https://kotlin.link/)
* [公式 Blog](https://blog.jetbrains.com/kotlin/)
* [助走読本](https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view)
　→ Kotlin第一人者が集まって書いた本。まずは目を通してみるのおすすめ

### Spring Boot

[power of Spring Boot and Kotlin.](https://spring.io/guides/tutorials/spring-boot-kotlin/)


[Spring初学者が最初に知るべき責務とレイヤー](https://www.yo1000.com/spring-responsibilities/)


### Wikipedia

[Kotlin \- Wikipedia](https://ja.wikipedia.org/wiki/Kotlin)

* Kotlin言語は、Java言語をもっと簡潔・安全になるように改良した産業利用向け汎用言語として開発された。
* オペレーティング・システムによらずJava仮想マシン上で動く。
* Java言語で書かれたプログラムと同じほど速くコンパイルされ同じほど速く動作するとしている。
* Java言語に望まれている機能であっても互換性を保つために実現できていない機能や、将来のJava言語の仕様で実現が予定されている機能から、有用と思われる機能を採用した。
* Java仮想マシンで動く点で似ているスクリプト言語 Groovy や関数型プログラミング言語の要素が強い Scala から、機能や簡易記法（糖衣構文）を採用した。
* [ジェネリック](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)の構文などでC#の影響を受けている部分もある。 `List<T>`など。
* [コトリン島](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%88%E3%83%AA%E3%83%B3%E5%B3%B6)にちなんで命名された。コトリンは、開発の地サンクトペテルブルクに近いバルト海フィンランド湾にあり、全長約12kmの細長い島である。
* [Kotlin/Native \- Kotlin Programming Language](https://kotlinlang.org/docs/reference/native-overview.html)がある。



# 開発構築の構築

ローカル開発構築の構築について

## JVMとJDK

まずはJVMとJDKについて知識があった方がよい。既知の場合には読み飛ばしてOK


* [JVM言語とJDKの関係を理解する \- Qiita](https://qiita.com/kmizu/items/a9bd5035a30397da3401)

**気になる箇所を抜粋**

>* ScalaやKotlinが生成したクラスファイルは新しいJVMでも（ほぼ）そのまま実行できる
* ScalaやKotlinのコンパイラ、Apache GroovyやClojureのように実行時にコンパイルを行うものについては、新しいJDK上で動かすために改修が必要になる可能性がある
    * ただし、既存のプログラムをそのままコンパイルできるようにするだけなら、必要な変更は多くない


## JDKの有料・無料・サポート等について

KotlinにはJDKが必要だが、Oracle版JDKは有料サポートとなった。
広く使われてきたOracle版からの代替えが必要となった。（※有料にしない場合）

* [Oracle Java SEの有償化に伴うOpenJDKへの切り替えの案内 \| 京都教育大学 情報処理センター](https://ipc.kyokyo-u.ac.jp/page/696)
* [Oracle Java 更新版公開、ただしライセンス変更に注意。抵触する場合はOpenJDKへの移行を](https://www.st.ryukoku.ac.jp/blog/vuln/01058)
* [OpenJDK完全互換、Amazon Correttoは信用できるのか \- orangeitems’s diary](https://www.orangeitems.com/entry/2018/11/15/101955)


**気になる箇所を抜粋**

>個人的な意見としては、AWSによるベンダーロックインがJavaというアプリケーションの中核でも進んでしまうことの解釈が問題の焦点だと思います。今のAmazon Linux 2のように、CorrettoはAWSに限定して使われると思っています。


## JDK のInstall について

### Amazon Coretto の場合

* [Amazon Corretto インストーラー﻿](https://aws.amazon.com/jp/corretto/)
* [macOS 10\.13 以降で Amazon Corretto 11 をインストールする手順](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-11-ug/macos-install.html)
* [Windows 7 以降で Amazon Corretto 11 をインストールする手順](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-11-ug/windows-7-install.html)

### AdpotOpenJDK の場合

[HomebrewでAdpotOpenJDKをインストールする \- Qiita](https://qiita.com/suin/items/a898618eb542c77cc53b)


### JDKのバージョン確認 (Mac)

今何が入ってたっけ？という時、
インストールされているJDKのバージョンを確認する

```shell
/usr/libexec/java_home -V
```

有効(アクティブ)なJDKのバージョンを確認するには以下

```shell
java -version
```



### Javaの切り替え (Mac)

アクティブなJavaを切り替える。
AdpotOpenJDK → corretto11などの場合には以下を行う。

corretto11の場合、ターミナルで以下を実行する。
（バージョンに依存するので、実際の操作時には公式サイトを見る事）

```shell
export JAVA_HOME=/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
```

これで切り替わらない場合、以下のように.bash_profileに追加する。
.bash_profileはログイン時に実行される。


```shell
vi .bash_profile

以下を追加
export JAVA_HOME=/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
```


## 開発環境 IDEについて

### IntelliJ IDEA

**IDEはIntelliJ IDEA (インテリジェイ アイディア)を使う**



* [IntelliJ IDEA公式サイト - JetBrains](https://www.jetbrains.com/idea/?fromMenu)
* [日本代理店 - IntelliJ IDEA Ultimate 2019\.1 \| 株式会社サムライズム](https://samuraism.com/jetbrains/intellij-idea)
* [IntelliJ IDEA \- Wikipedia](https://ja.wikipedia.org/wiki/IntelliJ_IDEA)

>IntelliJ IDEA (インテリジェイ アイディア) は、チェコに本社を置くJetBrains社が開発した、Javaなど数多くのプログラミング言語に対応した統合開発環境である。


### Ultimate or Community ?

Commercial or 'Open-source, Apache 2.0'
どちらを使うか？

[ダウンロードページ](https://www.jetbrains.com/idea/download/)のOpen-source, Apache 2.0の右側にカーソルあてると↓のように表示される。
<img width="910" alt="スクリーンショット 2019-07-10 11.49.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/b0968e67-fab7-ea7d-493f-3b81196ed155.png">

>Community Edition is open-source, licensed under Apache 2.0. Projects like Android and Swift use Apache 2.0, so you’re in good company.
It can also be used for commercial development.

### Community版の特徴

* 対応言語がJava、Scala、Groovy、Clojure、KotlinなどのJavaプラットフォーム上の言語のみ。PHP、Python、Rubyなどは非対応。
* Web系非対応。HTML、JavaScript、Webフレームワーク（Grailsなど）、Webサービスなどは非搭載
* エンタープライズ系非対応。Java EE非対応。
* データベース系非対応。SQL非対応、データベースツールを搭載しない。
* UMLデザイナ非搭載
* モバイル系はAndroidのみ対応。Adobe AIR非対応。
* アジャイル開発系非対応。

### IDEのインストール

インストールは特に迷う事が無いと思うので割愛



# 開発スタート

準備ができたところでKotlinに触れていきます。

## Try it

さっそくIDEで開発を・・・の前に、まずはWeb上の実行環境でKotlinを試してみましょう。
以下にアクセスします。

https://try.kotlinlang.org/

まずは定番のHello, world!から。

### Hello, world!

[Hello, world! するサンプル | Try Kotlin](https://try.kotlinlang.org/#/Examples/Hello,%20world!/Simplest%20version/Simplest%20version.kt)


Run をぽちっと押すと、下のコンソールエリアに、Hello, world! と表示されます。このへんは特に説明は要らないと思います。
<img width="980" alt="スクリーンショット 2019-07-10 14.51.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/53bcc0ae-01d0-f6b1-1da6-343a8e0cbdfc.png">

mainの基本形は`fun main(args: Array<String>)`といったように`Array<String>`の引数を受けますが、引数を使わない場合には`fun main()`と省略も可能のようです。

```kotlin
fun main() {
    println("Hello, world!")
}
```

### 引数をセットする

[引数をセットするサンプル | Try Kotlin](https://try.kotlinlang.org/#/Examples/Hello,%20world!/Reading%20a%20name%20from%20the%20command%20line/Reading%20a%20name%20from%20the%20command%20line.kt)

引数（args）をセットしたい場合には以下の場所に入力します。
<img width="979" alt="スクリーンショット 2019-07-10 14.56.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/0f3db17d-3c36-d4af-8a84-46117621cdfe.png">

`args`に値が格納されるので以下のように使います。
argsが空の場合にはargs.sizeが０になっているので、それで判定します。

```kotlin
fun main(args: Array<String>) {
    if (args.size == 0) {
        println("Please provide a name as a command-line argument")
        return
    }
    println("Hello, ${args[0]}!")
}
```

ちなみに、`${args[0]}`は「Stringテンプレート」という機能です。
文字列中に$(ドル記号)とともに変数や式を挿入する

[string templatesの説明](https://kotlinlang.org/docs/reference/coding-conventions.html#string-templates)


### 引数を使う

複数の値が引数にセットされた場合の処理

[引数を使うサンプル | Try Kotlin](https://try.kotlinlang.org/#/Examples/Hello,%20world!/Reading%20many%20names%20from%20the%20command%20line/Reading%20many%20names%20from%20the%20command%20line.kt)

argsがジェネリクス`Array<String>`になっているので、argsをforで回して使うサンプルです。

```kotlin
fun main(args: Array<String>) {
    for (name in args)
        println("Hello, $name!")
}
```

forEachで回す場合には以下のようになります。

```kotlin
fun main(args: Array<String>) {
    //ラムダを使う場合
    args.forEach{ element -> println("Hello, $element!") }

    //ラムダを使わない場合には it が利用できる
    args.forEach{ println("Hello, $it!") }
}
```

#### 参考

* [リストの要素分ループして操作する - 逆引きKotlin](http://kotlin-rev-solution.herokuapp.com/site/collection-for-each/)
* [forEach - Kotlin Programming Language](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/for-each.html)
* [Kotlin のコレクション使い方メモ - Qiita](https://qiita.com/opengl-8080/items/36351dca891b6d9c9687)


### オブジェクト志向的

[オブジェクト志向的 Hello | Try Kotlin](https://try.kotlinlang.org/#/Examples/Hello,%20world!/An%20object-oriented%20Hello/An%20object-oriented%20Hello.kt)

```kotlin
class Greeter(val name: String) {
    fun greet() {
        println("Hello, ${name}");
    }
}

fun main(args: Array<String>) {
    Greeter(args[0]).greet()
}
```

これが読みにくい場合には以下だとわかりやすいかも？

```kotlin
fun main(args: Array<String>) {
    var greeter = Greeter(args[0])
    greeter.greet()
}
```

サンプルは他にもたくさんあるので、一通りやってみた方がよい


## ローカル環境でのKotlin始め

主にバックエンドで使用する想定で進めていきます。

## Rest API

[Kotlin + Spring Boot でHello! World! - Qiita](https://qiita.com/sugasaki/items/d42d017961a97f5363ee)

[Kotlin + Spring Boot \+ Swagger - Qiita](https://qiita.com/sugasaki/items/c19821bfe483d45b2415)


[IntelliJ IDEA で　JavaSDKを変更する - Qiita](https://qiita.com/sugasaki/items/49408d3d1d9c9885b103)


## Actuator

[Spring Boot > Actuator - Qiita](https://qiita.com/sugasaki/items/b62e89af6b70b5199d1c)


## Async (非同期処理)


[Kotlin > @Asyn (非同期処理) - Qiita](https://qiita.com/sugasaki/items/5989faaf5dc5ec06fea8)



## コルーチン

[実例によるkotlinx\.coroutinesの手引き（日本語訳） \- Qiita](https://qiita.com/pljp/items/a1f3e8d1d13c88a94907)

kotlinx.coroutines はJetBrainsによって開発されたコルーチン用の豊富なライブラリです。

言語としてのKotlinは、他の様々なライブラリがコルーチンを利用できるようにするために標準ライブラリに最小限の低レベルAPIしか提供していません。 
同様の機能を持つ他の多くの言語とは異なり、 async と await はKotlinのキーワードではなく、標準ライブラリの一部でもありません。


# Test


[Tutorial · Building web applications with Spring Boot and Kotlin](https://spring.io/guides/tutorials/spring-boot-kotlin/#_testing_with_junit_5)


```kotlin
tasks.withType<Test> {
  useJUnitPlatform()
}
```


```
dependencies {
...
	testCompile("org.springframework.boot:spring-boot-starter-test") {
		exclude(module = "junit")
	}
	testImplementation("org.junit.jupiter:junit-jupiter-api")
	testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
	testImplementation("com.ninja-squad:springmockk:1.1.2")
...
}
```


# 参考等

[What's Good About Kotlin in Android Development - Shiraji's Blog](https://shiraji.github.io/blog/2016/12/11/whats-good-about-kotlin-in-android-development/)