源代碼下載: LearnKotlin-cn.kt
Kotlin是一門適用於JVM、Android和瀏覽器的靜態類型編程語言。它 100% 兼容 Java,瞭解更多。
// 單行註釋從 // 開始
/*
多行註釋看起來像這樣。
*/
// "package" 關鍵字的工作方式與Java相同。
package com.learnxinyminutes.kotlin
/*
Kotlin程序的入口點是一個"main"函數
該函數傳遞一個包含所有命令行參數的數組。
*/
fun main(args: Array<String>) {
/*
使用"var"或"val"來聲明一個值。
"val"聲明的值不能被重新賦值,而"var"聲明的值可以。
*/
val fooVal = 10 // 以後我們不能再次給fooVal賦值
var fooVar = 10
fooVar = 20 // fooVar可以被再次賦值
/*
在大多數情況下,Kotlin可以確定變量的類型是什麼,
所以我們不必要每次都去明確指定它。
我們可以像這樣明確地聲明一個變量的類型:
*/
val foo: Int = 7
/*
可以採取和Java類似的方法來表示一個字符串。
用反斜槓來轉義字符。
*/
val fooString = "My String Is Here!";
val barString = "Printing on a new line?\nNo Problem!";
val bazString = "Do you want to add a tab?\tNo Problem!";
println(fooString);
println(barString);
println(bazString);
/*
原始字符串用三重引號(""")來定義。
原始字符串可以包含換行符以及其他任何字符。
*/
val fooRawString = """
fun helloWorld(val name : String) {
println("Hello, world!")
}
"""
println(fooRawString)
/*
字符串可以包含模板表達式。
模板表達式從一個美元符號($)開始。
*/
val fooTemplateString = "$fooString has ${fooString.length} characters"
println(fooTemplateString) // => 輸出 My String Is Here! has 18 characters
/*
當某個變量的值可以為 null 的時候,我們必須明確指定它是可為空的。
在變量聲明處的類型後面加上?來標識它是可為空的。
我們可以用?.操作符來訪問可為空的變量。
我們可以用?:操作符來指定一個在變量為空時使用的替代值。
*/
var fooNullable: String? = "abc"
println(fooNullable?.length) // => 3
println(fooNullable?.length ?: -1) // => 3
fooNullable = null
println(fooNullable?.length) // => null
println(fooNullable?.length ?: -1) // => -1
/*
使用"fun"關鍵字來聲明一個函數。
函數的參數在函數名後面的括號內指定。
函數的參數可以設定一個默認值。
如果需要的話,函數的返回值類型可以在參數後面指定。
*/
fun hello(name: String = "world") : String {
return "Hello, $name!"
}
println(hello("foo")) // => Hello, foo!
println(hello(name = "bar")) // => Hello, bar!
println(hello()) // => Hello, world!
/*
函數的可變參數可使用 "vararg" 關鍵字來修飾
*/
fun varargExample(vararg names: Int) {
println("Argument has ${names.size} elements")
}
varargExample() // => 傳入 0 個參數
varargExample(1) // => 傳入 1 個參數
varargExample(1, 2, 3) // => 傳入 3 個參數
/*
當函數只包含一個單獨的表達式時,大括號可以省略。
函數體可以寫在一個=符號後面。
*/
fun odd(x: Int): Boolean = x % 2 == 1
println(odd(6)) // => false
println(odd(7)) // => true
// 如果返回值類型可以推斷,那麼我們不需要指定它。
fun even(x: Int) = x % 2 == 0
println(even(6)) // => true
println(even(7)) // => false
// 函數可以用函數作為參數並且可以返回函數。
fun not(f: (Int) -> Boolean) : (Int) -> Boolean {
return {n -> !f.invoke(n)}
}
// 普通函數可以用::運算符傳入引用作為函數參數。
val notOdd = not(::odd)
val notEven = not(::even)
// lambda 表達式可以直接作為參數傳遞。
val notZero = not {n -> n == 0}
/*
如果一個 lambda 表達式只有一個參數
那麼它的聲明可以省略(連同->),內部以 "it" 引用。
*/
val notPositive = not {it > 0}
for (i in 0..4) {
println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")
}
// "class"關鍵字用來聲明類。
class ExampleClass(val x: Int) {
fun memberFunction(y: Int) : Int {
return x + y
}
infix fun infixMemberFunction(y: Int) : Int {
return x * y
}
}
/*
我們調用構造方法來創建一個新的實例。
注意,Kotlin沒有"new"關鍵字。
*/
val fooExampleClass = ExampleClass(7)
// 可以使用一個點號來調用成員方法。
println(fooExampleClass.memberFunction(4)) // => 11
/*
如果使用"infix"關鍵字來標記一個函數
那麼可以使用中綴表示法來調用該函數。
*/
println(fooExampleClass infixMemberFunction 4) // => 28
/*
數據類是創建只包含數據的類的一個簡潔的方法。
"hashCode"、"equals"和"toString"方法將自動生成。
*/
data class DataClassExample (val x: Int, val y: Int, val z: Int)
val fooData = DataClassExample(1, 2, 4)
println(fooData) // => DataClassExample(x=1, y=2, z=4)
// 數據類有一個"copy"函數
val fooCopy = fooData.copy(y = 100)
println(fooCopy) // => DataClassExample(x=1, y=100, z=4)
// 對象可以被解構成為多個變量
val (a, b, c) = fooCopy
println("$a $b $c") // => 1 100 4
// "with"函數類似於JavaScript中的"with"用法。
data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
val fooMutableData = MutableDataClassExample(7, 4, 9)
with (fooMutableData) {
x -= 2
y += 2
z--
}
println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
/*
我們可以使用"listOf"函數來創建一個list。
這個list是不可變的 - 元素不可以被添加或刪除。
*/
val fooList = listOf("a", "b", "c")
println(fooList.size) // => 3
println(fooList.first()) // => a
println(fooList.last()) // => c
// 可以通過索引來訪問list中的元素。
println(fooList[1]) // => b
// 可以使用"mutableListOf"函數來創建一個可變的list。
val fooMutableList = mutableListOf("a", "b", "c")
fooMutableList.add("d")
println(fooMutableList.last()) // => d
println(fooMutableList.size) // => 4
// 我們可以使用"setOf"函數來創建一個set。
val fooSet = setOf("a", "b", "c")
println(fooSet.contains("a")) // => true
println(fooSet.contains("z")) // => false
// 我們可以使用"mapOf"函數來創建一個map。
val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
// 可以通過鍵來訪問map中的值。
println(fooMap["a"]) // => 8
/*
序列表示惰性求值集合。
我們可以使用"generateSequence"函數來創建一個序列。
*/
val fooSequence = generateSequence(1, {it + 1})
val x = fooSequence.take(10).toList()
println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 一個用序列來生成斐波那契數列的例子。
fun fibonacciSequence() : Sequence<Long> {
var a = 0L
var b = 1L
fun next() : Long {
val result = a + b
a = b
b = result
return a
}
return generateSequence(::next)
}
val y = fibonacciSequence().take(10).toList()
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
// Kotlin為集合提供高階函數。
val z = (1..9).map {it * 3}
.filter {it < 20}
.groupBy {it % 2 == 0}
.mapKeys {if (it.key) "even" else "odd"}
println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]}
// 任何提供迭代器的都可以使用"for"循環。
for (c in "hello") {
println(c)
}
// "while"循環的用法和其他語言一樣。
var ctr = 0
while (ctr < 5) {
println(ctr)
ctr++
}
do {
println(ctr)
ctr++
} while (ctr < 10)
// "when"可以用來替代"if-else if"鏈。
val i = 10
when {
i < 7 -> println("first block")
fooString.startsWith("hello") -> println("second block")
else -> println("else block")
}
// "when"可以帶參數。
when (i) {
0, 21 -> println("0 or 21")
in 1..20 -> println("in the range 1 to 20")
else -> println("none of the above")
}
// "when"可以作為一個函數,提供返回值。
var result = when (i) {
0, 21 -> "0 or 21"
in 1..20 -> "in the range 1 to 20"
else -> "none of the above"
}
println(result)
/*
我們可以通過使用"is"操作符來檢查一個對象是否是某個類型的。
如果對象通過了類型檢查那麼它可以作為該類型使用而不需要強制轉換它。
*/
fun smartCastExample(x: Any) : Boolean {
if (x is Boolean) {
// x自動轉換為Boolean
return x
} else if (x is Int) {
// x自動轉換為Int
return x > 0
} else if (x is String) {
// x自動轉換為String
return x.isNotEmpty()
} else {
return false
}
}
println(smartCastExample("Hello, world!")) // => true
println(smartCastExample("")) // => false
println(smartCastExample(5)) // => true
println(smartCastExample(0)) // => false
println(smartCastExample(true)) // => true
/*
擴展是用來給一個類添加新的功能的。
它類似於C#的擴展方法。
*/
fun String.remove(c: Char): String {
return this.filter {it != c}
}
println("Hello, world!".remove('l')) // => Heo, word!
println(EnumExample.A) // => A
println(ObjectExample.hello()) // => hello
}
// 枚舉類和Java的枚舉類型類似。
enum class EnumExample {
A, B, C
}
/*
"object"關鍵字用來創建單例對象。
我們不能把它賦給一個變量,但我們可以通過它的名字引用它。
這類似於Scala的單例對象。
*/
object ObjectExample {
fun hello() : String {
return "hello"
}
}
進一步閲讀
- Kotlin教程
- 在您的瀏覽器中使用Kotlin
- Kotlin資源列表
有建議?或者發現什麼錯誤?在 Github 上開一個 issue ,或者發起 pull request!
原文由 S Webber 編寫,並由 0 個好心人 修改。
Translated by:Jimin Lu
© 2022 S Webber
本作品採用 CC BY-SA 3.0 協議進行許可。