Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> KOTLIN開發語言文檔(官方文檔),kotlin開發語言

KOTLIN開發語言文檔(官方文檔),kotlin開發語言

編輯:關於android開發

KOTLIN開發語言文檔(官方文檔),kotlin開發語言


網頁鏈接:https://kotlinlang.org/docs/reference/basic-types.html

2.   基本概念

2.1.  基本類型

從可以在任何變量處理調用成員函數和屬性角度來說,在Kotlin開發語言中,一切都是對象。有些類型是內嵌的,它們的實現進行過優化,用戶看到的仍是原始類。在這節中,我們說明大部分這些類型:數字,字符,布爾和數組。

2.1.1.   數字

Kotlin開發語言處理數組的方法類似Java開發語言,但是也有差別。例如,沒有隱含的數字擴寬的轉換,並且在相同的情況下,文字也有些不同。

Kotlin開發語言提供下列內嵌類型表示數字(這是類似Java開發語言):

類型

位寬度

Double

64

Float

32

Long

64

Int

32

Short

16

Byte

8

 

 

 

 

 

 

 

 

 

 

注意,在Kotlin開發語言中,字符不屬於數組。

2.1.1.1. 文字常數

對於整數值有下面幾種文字常數:

—— 十進制數:123

—— 附加大寫字母L標准長整數:123L

—— 十六進制數:0x0F

—— 二進制數:0b00001011

注意:不支持八進制數字。

Kotlin開發語言還支持通用的浮點數表示法:

—— 默認是雙精度:123.5,123.5e10

—— 附加f或F表示單精度浮點數:123.5F

2.1.1.2. 表示法

在Java開發語言平台上,數字是作為JVM基本類型進行物理存在的,除非需要一個可null數字引用(如:Int?)或包含在泛型。後一種情況下,是將數字裝箱的。

注意數字裝箱不保持一致性:

1 val a: Int = 10000
2 print(a === a) // 打印 'true'
3 val boxedA: Int? = a
4 val anotherBoxedA: Int? = a
5 print(boxedA === anotherBoxedA) // !!!打印 'false'!!!

而另一方面,卻保持相等:

1 val a: Int = 10000
2 print(a == a) // 打印 'true'
3 val boxedA: Int? = a
4 val anotherBoxedA: Int? = a
5 print(boxedA == anotherBoxedA) // 打印 'true'

2.1.1.3. 顯式轉換

由於不同的表示法,較小類型不是較大類型的子類型。如果是,就有下列麻煩了:

1 // 假設代碼,沒有實際編譯:
2 val a: Int? = 1 // 裝箱為Int (java.lang.Integer)
3 val b: Long? = a // 隱含轉換裝箱為Long (java.lang.Long)
4 print(a == b) // 令人驚訝! 當equals()檢查其它部分不是Long,就打印"false"

所以不僅僅是一致性,而且即使相當也會在此默默丟失一部分。

這樣,較小的類型不會隱含的轉換為較大的類型。這就是說,如果沒有進行明確的類型轉換,Byte類型值是不能賦值給Int類型變量。

1 val b: Byte = 1 // OK, 靜態文字檢查
2 val i: Int = b // 錯誤

可以進行明確(顯式)的數字寬度轉換:

1 val i: Int = b.toInt() // OK: 顯式寬度轉換

每項數字類型支持下列轉換:

toByte(): Byte

—toShort(): Short

—toInt(): Int

—toLong(): Long

—toFloat(): Float

—toDouble(): Double

—toChar(): Char

因為類型是從上下文推斷,以及適當的轉換重載了算術運算符,所以隱式轉換缺位是很少引人注目的,例如:

1 val l = 1L + 3 // Long + Int => Long

2.1.1.4. 運算

Kotlin開發語言支持對數字標准的一套運算,它們被聲明為相應類成員(但是,編譯器優化調用的相應指令)。查看:運算符重載(5.6)。

作為位運算,對於它們沒有特殊特性(字符),僅僅命名函數使其能以中綴方式被調用,如:

1 val x = (1 shl 2) and 0x000FF000

這是完整的位運算列表(僅僅對Int和Long類型有效):

— shl(bits) – signed shift left (Java’s <<)

— shr(bits) – signed shift right (Java’s >>)

— ushr(bits) – unsigned shift right (Java’s >>>)

— and(bits) – bitwise and

— or(bits) – bitwise or

— xor(bits) – bitwise xor

— inv() – bitwise inversion

2.1.2.   字符

char類型表示字符。它們不能直接作為數組處理:

1 fun check(c: Char) {
2   if (c == 1) { // ERROR: incompatible types
3     // ...
4   }
5 }

字符文字是在單引號中:’1’,’\n’,’\uFF00’。我們能夠明確地轉換字符到Int數字:

1 fun decimalDigitValue(c: Char): Int {
2   if (c !in '0'..'9')
3     throw IllegalArgumentException("Out of range")
4   return c.toInt() - '0'.toInt() // Explicit conversions to numbers
5 }

在需要可null引用時,像數字、字符是被裝箱。裝箱操作是不保證一致性的。

2.1.3.   布爾值

Boolean類型表示布爾值,它有兩個值:true和false。

如果需要可null引用時,布爾值可以被裝箱的。

布爾值的內置的運算包括:

— || – lazy分離 (注:這個“lazy”不知道怎樣翻譯好,就是 “或”為啥要這樣?)

— && – lazy連接

— ! – 非

2.1.4.   數組

在Kotlin開發語言中,Array類表示數組,它有get和set函數(即通過操作符重載約定轉成[]),有size屬性,以及其他一些有用的成員函數:

1 class Array<T> private constructor() {
2   val size: Int
3   fun get(index: Int): T
4   fun set(index: Int, value: T): Unit
5 
6   fun iterator(): Iterator<T>
7   // ...
8 }

可以用庫函數arrayOf(),將數組各項的數值傳遞給它,來創建一個數組,如:arrayOf(1,2,3)創建數組[1,2,3]。或者,用arrayOfNulls()庫函數創建一個指定尺寸(size)的數組,其元素均填充為null。

另一種選擇是用工廠函數獲得數組尺寸,並且返回指定索引位置的數組元素的初始值:

1 // Creates an Array<String> with values ["0", "1", "4", "9", "16"]
2 val asc = Array(5, { i -> (i * i).toString() })

如上所述,[]操作符表示調用成員函數get()和set()。

注意:與Java開發語言不同,在Kotlin開發語言中,數組是不變量。這意味著kotlin開發語言不允許賦值Array<String>到Array<Any>,這防止運行的可能的錯誤(但是,可以用Array<out Any>,查看:類型推測(3.7.2))。

Kotlin開發語言也有專用類表示原始類型的數組,不需要裝箱消耗:ByteArray、ShortArray、IntArray等等。這些類與Array類沒有繼承關系,但是它們有相同的一組方法和屬性。它們中的每一個都有相應的工廠函數:

1 val x: IntArray = intArrayOf(1, 2, 3)
2 x[0] = x[1] + x[2]

2.1.5.   串

String類型表示串。String是不可變的。串的元素是字符,可以用索引操作訪問:s[i]。可以用for循環遍歷一個串:

1 for (c in str) {
2   println(c)
3 }

2.1.5.1. 串文字

Kotlin開發語言有兩種串文字類型:包含轉義字符的轉義串和包含任意字符和新行符的原始串。轉義串非常像Java開發語言的串:

1 val s = "Hello, world!\n"

轉義可以用習慣的方法(用\)實現。

原始串由三引號(”””)定界的,包含非轉義字符、新行符,以及其它任意字符:

1 val text = """
2   for (c in "foo")
3     print(c)
4 """

2.1.5.2. 串模板

串可以包含模板表達式,即:可計算的代碼片段,其結果鏈接到串中。模板表達式以美元符號($)開始,和簡單的名字構成:

1 val i = 10
2 val s = "i = $i" // 計算結果是 "i = 10"

或是在大括號中的任意表達式:

1 val s = "abc"
2 val str = "$s.length is ${s.length}" // 計算結果是 "abc.length is 3"

在原始串和轉義串中,都支持模板。如果需要表達$字符文字,則可以用下列語法:

1 val price = "${'$'}9.99"

2.2.  包

一個源文件可以是從聲明包開始的:

1 package foo.bar
2 
3 fun baz() {}
4 class Goo {}
5 // ...

源文件中的所有內容(如:類和函數)都包含在包的聲明中。所以,在上面例子中,baz()的完整名稱是foo.bar.baz,Goo的完整名稱是foo.bar.Goo。

如果源文件中沒有指明包,則這個文件中的內容屬於沒有名稱的“默認”包。

2.2.1.   導入(import)

除默認的import外,每個文件都可以有自己的import偽指令。Import的句法在語法(6.2)中描述了。

我們既可以導入單個名稱,如:

1 import foo.Bar // Bar is now accessible without qualification

也可以是范圍內所有可訪問的內容(包、類、對象等等):

1 import foo.* // everything in 'foo' becomes accessible

如果有命名沖突,可以在沖突項用as關鍵字重命名來消除:

1 import foo.Bar // Bar可以訪問
2 import bar.Bar as bBar // bBar 表示 'bar.Bar'

import關鍵字不限制導入的類;也可以用途導入其它聲明:

—— 頂層函數和屬性;

—— 在對象聲明(3.12.2)中聲明的函數和屬性;

—— 枚舉常數(3.11);

不像Java開發語言,Kotlin開發語言沒有獨立的“import static”句法;所有這些聲明都是用常規的import關鍵字來導入。

2.2.2.   頂層聲明的可視范圍

如果頂層聲明標注private,它是它所在文件的私有的(查看:可視性修飾符(3.4))

2.3.  控制流

2.3.1.   if表達式

在Kotlin開發語言中,if是一個表達式,即:它返回一個值。由於在此規則下普通if運行的很好,因此沒有三元運算符(?:else)。

 1 // 傳統用法
 2 var max = a 
 3 if (a < b) 
 4   max = b 
 5  
 6 // 帶else 
 7 var max: Int
 8 if (a > b) 
 9   max = a 
10 else 
11   max = b 
12  
13 // 作為表達式
14 val max = if (a > b) a else b

if分支可以是代碼塊,最後表達式是代碼塊的值:

1 val max = if (a > b) { 
2     print("Choose a") 
3     a 
4   } 
5   else { 
6     print("Choose b") 
7     b 
8   }

如果用if作為表達式,而不是語句(例如,返回它的值,或賦值給變量),表達式要求有else分支。

查看:if語法(6.2.3.4)

2.3.2.   when表達式

When替代了類似C開發語言的switch操作符。最簡單形式如此:

1 when (x) {
2   1 -> print("x == 1")
3   2 -> print("x == 2")
4   else -> { // Note the block
5     print("x is neither 1 nor 2")
6   }
7 }

when將變量與其的所有分支順序逐一匹配,直至找到條件相符的分支。when即可用作表達式,也可以用作語句,滿足條件的分支值就是整個表達式的值。如果它用作語句,個別分支的值將被忽略。(就如同if,每個分支可以是一個代碼塊,代碼塊中最後的表達式值就是其值。)

else分支等價與沒有其它分支滿足條件。如果when用作一個表達式,且編譯器無法驗證分支條件覆蓋了所有的可能情況,則強制性要求else分支。

如果多種情況都有相同的處理方法,也可以用逗號將分支條件組合起來:

1 when (x) {
2   0, 1 -> print("x == 0 or x == 1")
3   else -> print("otherwise")
4 }

可以用任意表達式(不僅僅是常數)作為分支條件:

1 when (x) {
2   parseInt(s) -> print("s encodes x")
3   else -> print("s does not encode x")
4 }

還可以用in或!in檢查一個范圍(5.2)或集合:

1 when (x) {
2   in 1..10 -> print("x is in the range")
3   in validNumbers -> print("x is valid")
4   !in 10..20 -> print("x is outside the range")
5   else -> print("none of the above")
6 }

另一種情況,可以用is或!is檢查特別類型。注意,由於智能轉換(5.4),不需要任何額外的檢查就可以訪問類型的方法和屬性:

1 val hasPrefix = when(x) {
2   is String -> x.startsWith("prefix")
3   else -> false
4 }

when還可以用來替換if-else鏈。如果沒有變量,分支條件就是簡單的布爾表達式,且在when條件為true時,執行該分支:

1 when {
2   x.isOdd() -> print("x is odd")
3   x.isEven() -> print("x is even")
4   else -> print("x is funny")
5 }

查看:when語法(6.2.3.4.2.1)。

2.3.3.   for循環

for循環遍歷提供的任何一個迭代器。句法如下:

1 for (item in collection)
2   print(item)

循環體可以是一個代碼塊。

1 for (item: Int in ints) {
2   // ...
3 }

如前所述,for循環遍歷提供的任何一個迭代器,即:

—— 有成員iterator()或擴展函數iterator(),它返回類型:

 —— 有成員next()或擴展函數next(),和

 —— 有返回布爾類型的成員hasNext()或擴展函數hasNext()。

所有這三個函數是需要作為操作符的。

如果要利用索引遍歷一個數組或列表,可以這樣做:

1 for (i in array.indices)
2   print(array[i])

注意,這句“遍歷一個范圍”是由編譯器優化實現的,不需要產生額外的對象。

或者,可以用withIndex庫函數:

1 for ((index, value) in array.withIndex()) {
2     println("the element at $index is $value")
3 }

查看:for語法(6.2.3.3)。

2.3.4.   while循環

while和do…while都是如常規一樣工作:

1 while (x > 0) {
2   x--
3 }
4 
5 do {
6   val y = retrieveData()
7 } while (y != null) // y is visible here!

查看:while語法(6.2.3.3)。

2.3.5.   循環的中斷和繼續

Kotlin開發語言支持循環中的傳統break和continue操作符。查看:返回和跳轉(2.4)。

2.4.  返回和跳轉

Kotlin開發語言有三種結構化的跳轉操作符:

—— return。默認情況下,由最近的函數返回,或匿名函數的返回。

—— break。終止最近一層循環。

—— continue。繼續最近一層循環的下一步。

2.4.1.   中斷和繼續標簽

在Kotlin開發語言中,任何表達式都可以帶標簽。標簽的格式是在標識符後跟@來表示,如:abc@,fooBar@都是合法的標簽(查看:語法(6.2))。為了標記表達式,只需要在其前面加上標簽即可:

1 loop@ for (i in 1..100) {
2   // ...
3 }

現在,就可以break或continue到標簽了:

1 loop@ for (i in 1..100) {
2   for (j in 1..100) {
3     if (...)
4       break@loop
5   }
6 }

帶有標簽的break跳轉到標記loop之後的執行點。Continue繼續進行標記loop的下一步。

2.4.2.   在標簽處返回

Kotlin開發語言在函數體、局部函數和對象表達式中,允許函數嵌套。Return允許我們有外部函數返回。最重要的用例是由Lambda表達式返回。我們這樣編寫回調:

1 fun foo() {
2   ints.forEach {
3     if (it == 0) return
4     print(it)
5   }
6 }

返回表達式是由最近函數返回,即:foo。(注意:這樣對Lambda表達式僅支持非局部返回到內嵌函數(4.1.5)。)如果要從Lambda表達式返回,就需要標記它限制返回:

1 fun foo() {
2   ints.forEach lit@ {
3     if (it == 0) return@lit
4     print(it)
5   }
6 }

現在,就僅從Lambda表達式返回。通常,最方便的是用隱含標簽:這樣標簽與傳遞給Lambda表達式的函數同名。

1 fun foo() {
2   ints.forEach {
3     if (it == 0) return@forEach
4     print(it)
5   }
6 }

或者,可以用匿名函數(4.2.3.3)替代Lambda表達式。在匿名函數中的return語句是從匿名函數自身返回。

1 fun foo() {
2   ints.forEach(fun(value: Int) {
3     if (value == 0) return
4     print(value)
5   })
6 }

當返回一個值是,解析器優先給出恰當的返回,如:

1 return@a 1

就是“在標簽@a處返回1”而不是“返回標簽表達式(@a 1)”。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved