Kotlin

**Kotlin** 是一種在 Java 虛擬機上執行的靜態型別程式語言，它也可以被編譯成為 JavaScript 原始碼。它主要是由俄羅斯聖彼得堡的 JetBrains 開發團隊所發展出來的程式語言，其名稱來自於聖彼得堡附近的科特林島。2012 年 1 月，著名期刊《Dr. Dobb's Journal》中 Kotlin 被認定為該月的最佳語言。雖然與 Java 語法並不相容，但在 JVM 環境中 Kotlin 被設計成可以和 Java 程式碼相互運作，並可以重複使用如 Java 集合框架等的現有 Java 參照的函式庫。Hathibelagal 寫道，「如果你正在為 Android 開發尋找一種替代程式語言，那麼應該試下 Kotlin。它很容易在 Android 專案中替代 Java 或者同 Java 一起使用。」

## 歷史

2011 年 7 月，JetBrains 推出 Kotlin 專案，這是一個面向 JVM 的新語言，它已被開發一年之久。JetBrains 負責人 Dmitry Jemerov 說，大多數語言沒有他們正在尋找的特性，但是 Scala 除外。但是，他指出 Scala 的編譯時間過慢這一明顯缺陷。Kotlin 的既定目標之一是像 Java 一樣快速編譯。2012 年 2 月，JetBrains 以 Apache 2 許可證開源此專案。

JetBrains 希望這個新語言能夠推動 IntelliJ IDEA 的銷售。

Kotlin v1.0 於 2016 年 2 月 15 日發布。這被認為是第一個官方穩定版本，並且 JetBrains 已準備從該版本開始的長期向下相容性。

在 Google I/O 2017 中，Google 宣布在 Android 上為 Kotlin 提供最佳支援。

## 語法

Kotlin 很明顯受到 Java、C#、JavaScript、Scala、Groovy 等語言的影響。例如 Kotlin 可以直接通過 `println("Hello, ${name}")` 或 `println("Hello, $name")` 來使用字串模板，和古老的 shell script 類似。又如 Kotlin 中的分號是可選的，這類似 JavaScript，而且 Groovy、Scala 也有同樣的能力。Kotlin 常數定義關鍵字是 `val`（不同於變數定義關鍵字 `var`），表示固定值，這功能來自 Scala，Swift 也有類似功能。

需要注意，Kotlin 沒有關鍵字 `new`。

### 變數

使用 `val`（全稱為 value，即（固定的）值）關鍵字定義唯讀變數，定義後其值無法修改

使用 `var`（全稱為 variable，即變數）關鍵字定義可變變數。

### 函式

使用 `fun` 關鍵字定義一個函式。

上例定義了一個傳入兩個 Int 變數，並返回兩數之和的求和函式。

### 程式的入口點

類似於 C、 C++、 C#、 Java 和 Go ， Kotlin 程式的入口點是一個名為「main」的函式。 main 函式有一個包含命令列選項的參數（從 Kotlin 1.3 開始是可選的）。 Kotlin 支援像 Perl 和 Unix shell 那樣的字串模板。 類型推斷也是支援的。

### 函式擴充

Kotlin 與 C#、JavaScript 類似，能夠擴充類別的新功能，而無需繼承該類別，或使用像裝飾器（decorator）這樣的任何類型的設計模式（design pattern）。擴充函式可以稱為 Kotlin 的核心，在標準庫里到處充斥著擴充函式。

擴充函式是靜態分發的，也就是說，它們不是以接收者類型為準的虛擬函式。這意味著呼叫的擴充函式是由函式呼叫所在的表達式的類型來決定的，而不是由表達式執行時求值結果決定的。

在下述例子中，String 類別被擴充出一個成員 lastChar。

利用函式擴充，Kotlin 也支援運算子多載：

### getter 和 setter

Kotlin 像 C# 一樣支援屬性（property）。

### 解包引數

類似 Python, 解包（unpack）指的是對實際參數的解包，只需在前面加一個星號 \* 即可，如 test（\*a）:

### 函式巢狀

Kotlin 支援函式巢狀（nested functions），允許函式內再定義函式，類似 JavaScript、C# 與 Python 語言。

### 解構聲明

Kotlin 支援解構聲明，這與 Python 的迭代解包相似。

例如，collection object 包含解構式可分離其元素:

### 抽象類別

抽象類別（Abstract classes）定義抽象或純虛擬（Pure Virtual）占位函式，需要被繼承。抽象類別預設是 open 的。

### 類別屬性

Kotlin 提供下列的關鍵字來限制頂層（top-level）聲明，用於控制類別與成員在繼承時的可見性（作用域）。它們可用於類別及其成員:

用於類別的成員聲明時，含義如下：

* public：全域可見。此為預設的類型。
* internal：在當前模組中可見。
* protected：在當前類別的一級子類別中可見，如果子類別再被繼承，則在下一級子類別中不可見。
* private：在當前類別中可見。

用於頂層聲明時，含義如下：

* public：全域可見。此為預設的類型。
* internal：在當前模組中可見。
* private：在當前檔案中可見。

例如:

### 主建構函式 vs. 二級建構函式

在 Kotlin 中類別可以有一個主建構函式以及多個二級建構函式。如果主建構函式沒有註解或可見性說明，則 `constructor` 關鍵字可以省略。如果建構函式中沒有其它操作，大括號也可以省略。

Kotlin 的二級建構函式更類似於 C++, C#, 和 Java。

### Anko library

Anko 是一組為 Kotlin 打造的函式庫，其功能是用來開發 Android UI 應用程式，現已棄用。

### Kotlin 互動模式

Kotlin 除了編譯成 Java 位元組碼執行，也可以作為手稿語言解釋執行，此特性使得 Kotlin 可以以互動模式執行。互動模式是手稿語言具有的特性，直譯器可以立即執行使用者輸入的代碼，並回饋執行結果。典型的語言有 Python、JavaScript（在 V8 引擎支援下）、Ruby。

### Kotlin 也是手稿語言

Kotlin 亦可視為手稿語言（scripting language）。其指令碼存成 Kotlin source file (.kts)，即成為可執行檔。

為了執行 Kotlin 指令碼，我們在執行編譯器時再加上-script 選項。

### Kotlin 的 hello world 例子

### 空變數及其運算

Kotlin 對可以為空（nullable）的變數和不可以為空（non-nullable）的變數作了區分。所有的可空物件（nullable objects）必須在定義時加上 "?" 後置於類型之後。開發人員遇到 nullable objects 時要先確認: null-check 須被執行過，才能賦值。可空性是 Kotlin 型別系統中幫助開發者避免以往 Java 的 NullPointerException 錯誤的特性。

Kotlin 提供空安全（null-safe）運算子給開發人員:

* ?. (Safe navigation operator) 可用於安全存取（safely access） 可能是空物件的函式或屬性。如果 object 為空（null）, 該方法將不被呼叫，而且表達式的值一定為空（null）。
* ?: (Null coalescing operator) 通常稱為艾維斯運算子（Elvis operator）:

使用安全導引（safe navigation）運算子:

### 高階函式與 lambda

Kotlin 亦支援高階函式和 lambdas 功能。lambda 是一種匿名函式，允許開發者直接將表達式定義為函式，這類似於 Python。

Lambdas 可用大括弧 { } 來定義。如果 lambda 夾帶參數，他們可定義在大括弧內，並以->運算子區隔。

## 參考資料

## 外部連結

* 官方網站
* 官方範例 （頁面存檔備份，存於網際網路檔案館）
* 官方網站 - 中文翻譯 （頁面存檔備份，存於網際網路檔案館）
* Kotlin 教學 （頁面存檔備份，存於網際網路檔案館）