提示:本文爲作者閱讀Kotlin中文站學習筆記,建議讀者移步Kotlin中文站完整學習。
包
源文件通常以包聲明開頭,源文件所有內容都包含在聲明的包內,如果沒有聲明包,文件內容屬於無聲明的默認包。當我們創建一個Kotlin文件時,Android studio會幫我們在文件頂部自動聲明包。
package com.gyg.kolin
Kotlin會默認導入一些包到文件中,除了默認導入的包,開發者也需要導入自己的包,可以單獨導入包下的某一個內容,也可以導入包下的所有內容。當命名衝突時,可以通過as關鍵字在本地重命名來消除歧義。
import foo.Bar//導入foo包下的Bar
import foo.*//導入foo包下的所有內容
import foo.Bar as Bar2//導入foo包下的額Bar,並且本地重命名爲Bar2
控制流
if表達式
在Kotlin中,if是一個表達式,它可以返回一個值。
val a:Int=23
val b:Int=46
val max:Int
max=if(a>b) a else b//if作爲一個表達式,當a>b時返回值a,否則返回值b
if的分支也可以是一個代碼塊,最後的表達式爲該塊的值
val a:Int=23
val b:Int=46
val max:Int
max=if(a>b){
print("max="+a)
a
}else{
print("max="+b)
b
}
注意:如果if作爲一個表達式使用,除非編譯器能夠檢測出所有的可能情況都已經覆蓋了,否則必須有else分支。
我們也可以像Java中一樣,把if作爲一個語句使用
val a:Int=23
val b:Int=46
val max:Int
if(a>b){
max=a
}else{
max=b
}
when表達式
when表達式,與Java中的switch語句類似。when 將它的參數和所有的分支條件順序比較,直到某個分支滿足條件。它可以被當作表達式使用, 符合條件的分支的值就是整個表達式的值。(像 if 一樣,每一個分支可以是一個代碼塊,它的值是塊中最後的表達式的值。)例如:
val a: Int = 3
val b: Int = 5
var max: Int
max = when (a > b) {
true -> {
print("max=a")
a
}
false -> {
print("max=b")
b
}
else -> {
print("a=b")
a
}
}
也可以當做語句使用, 忽略個別分支的值。
val a:Int=3
val b:Int=5
var max:Int
when(a>b){
true->{
print("max=a")
max=a
}
false->{
print("max=b")
max=b
}
else->{
print("a=b")
max=a
}
}
如果其他分支都不滿足條件將會求值 else 分支。 如果 when 作爲一個表達式使用,則必須有 else 分支, 除非編譯器能夠檢測出所有的可能情況都已經覆蓋了。
如果很多分支需要用相同的方式處理,則可以把多個分支條件放在一起,用逗號分隔:
var x:Int=0
when(x){
0,1-> print("x==1或x==2")
else-> print("otherwise")
}
我們可以用任意表達式(而不只是常量)作爲分支條件
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
我們也可以檢測一個值在(in)或者不在(!in)一個區間或者集合中:
val x:Int=5
val values:IntArray= intArrayOf(0,5,7,9)
when(x){
in 0..10->{//區間
print("x is in 0..10")
}
in values->{//集合
print("x is in values")
}
}
另一種可能性是檢測一個值是(is)或者不是(!is)一個特定類型的值。注意: 由於智能轉換,你可以訪問該類型的方法和屬性而無需任何額外的檢測。
fun getType(value:Any):Unit{
when(value){
is String-> print("value is a String type")
is Int-> print("value is Int type")
else-> print("value is not a String type or Int type")
}
}
如果不提供參數,所有的分支條件都是簡單的布爾表達式,而當一個分支的條件爲真時則執行該分支:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
For循環
for循環可以對任何提供迭代器(iterator)的對象進行遍歷,即這個對象:
有一個成員函數或者擴展函數iterator(),它的返回類型
- 有一個成員函數或擴展函數next(),返回這個對象的成員元素。並且
- 有一個成員函數或者擴展函數hasNext()返回Boolean。
這三個函數都要標記爲operator。
val str:String="Hello world"
for (item in str) print(item)
對數組的 for 循環會被編譯爲並不創建迭代器的基於索引的循環。
如果你想要通過索引遍歷一個數組或者一個 list,你可以這麼做:
for (i in array.indices) {
print(array[i])
}
注意這種“在區間上遍歷”會編譯成優化的實現而不會創建額外對象。
或者你可以用庫函數 withIndex:
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
While循環
我們可以以在Java中的相同姿勢來在Kotlin中使用while循環和do..while循環。
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此處可見
返回和跳轉
Kotlin有三種結構化跳轉表達式:
- return 默認從直接包圍它的函數或者匿名函數返回。
- break 默認終止最直接包圍它的循環.
- continue 默認繼續下一次最直接包圍它的循環。
這些表達式的類型都是Nothing類型。
所有這些表達式可以作爲包含它的更大表達式的一部分:
val name=person.name?:return
Break,Continue標籤
Kotlin中,我們可以用標籤來標記一個表達式,標籤的格式爲:標籤字符後跟@符號,例如:abc@,foreach@等等。要爲一個表達式加標籤,我們只要在其前加標籤即可。
abc@ for (item in str) print(item)
我們可以用標籤來限制break和continue表達式:
outer@for (i in 0..10){
innrer@for (j in 0..10){
if (i==3&&j==3)continue@outer
if (i==5&&j==5) break@outer
}
}
標籤限制的break跳轉到更好位於該標籤指定的循環後面的執行點,continue繼續標籤指定的循環的下一次循環。
標籤處返回
Kotlin中,return語句是從最直接包含它的fun標記的函數中返回,例如下面這樣:
fun foo() {
ints.forEach {
if (it == 0) return
print(it)
}
}
ruturn 直接從foo()函數中返回,如果我們要從lambda表達式中返回,必須給它加標籤並用以限制return表達式:
fun foo() {
ints.forEach @lambda{
if (it == 0) return@lambda
print(it)
}
}
這樣,return就會從lambda函數中返回。或者更方便的,我們可以使用隱式標籤,它與接受該lambda表達式的函數同名:
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
或者,我們用匿名函數來代替lambda表達式,匿名函數裏的return表達式,將直接從該匿名函數中返回。
fun foo() {
ints.forEach(fun(value: Int) {
if (value == 0) return
print(value)
})
}
當要返回一個值的時候,解析器優先選用標籤限制的 return,即
return@a 1
意爲“從標籤 @a 返回 1”,而不是“返回一個標籤標註的表達式 (@a 1)”。