《Kotlin極簡(jiǎn)教程》第三章 Kotlin基本數(shù)據(jù)類型

正式上架:《Kotlin極簡(jiǎn)教程》Official on shelves: Kotlin Programming minimalist tutorial
京東JD:https://item.jd.com/12181725.html
天貓Tmall:https://detail.tmall.com/item.htm?id=558540170670

在 Kotlin 中,所有東西都是對(duì)象:數(shù)字、字符、布爾和數(shù)組。(JavaScript)

數(shù)字

Kotlin 提供了如下的內(nèi)置類型來表示數(shù)字(長(zhǎng)度bit):

Double(64)
Float(32)
Long(64)
Int(32)
Short(16)
Byte(8)

在 Kotlin 中字符不是數(shù)字字面常量。
數(shù)值常量字面值有以下幾種:

十進(jìn)制: 123
Long 類型用大寫 L
標(biāo)記: 123L
十六進(jìn)制: 0x0F
二進(jìn)制: 0b00001011

注意: 不支持八進(jìn)制

Kotlin 同樣支持浮點(diǎn)數(shù)的常規(guī)表示方法:

 double:123.5, 123.5e10

Float 用 f 或者 F
 標(biāo)記: 123.5f

每個(gè)數(shù)字類型支持如下的轉(zhuǎn)換:

toByte(): Byte

toShort(): Short

toInt(): Int

toLong(): Long

toFloat(): Float

toDouble(): Double

toChar(): Char

缺乏隱式類型轉(zhuǎn)換并不顯著,因?yàn)轭愋蜁?huì)從上下文推斷出來,而算術(shù)運(yùn)算會(huì)有重載做適當(dāng)轉(zhuǎn)換,例如:

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

布爾類型

Boolean,它有兩個(gè)值:truefalse。
若需要可空引用布爾會(huì)被裝箱。
內(nèi)置的布爾運(yùn)算有:

||  短路邏輯或
&&  短路邏輯與
!   邏輯非

數(shù)組

數(shù)組在 Kotlin 中使用 Array類來表示,它定義了 :

get和 set函數(shù)(按照運(yùn)算符重載約定這會(huì)轉(zhuǎn)變?yōu)?[])
size屬性

以及一些其他有用的成員函數(shù):

class Array<T> private constructor() { 
    val size: Int fun get(index: Int): T 
    fun set(index: Int, value: T): Unit 
    fun iterator(): Iterator<T> // ...
}

我們可以使用庫函數(shù) arrayOf()
來創(chuàng)建一個(gè)數(shù)組并傳遞元素值給它,這樣

arrayOf(1, 2, 3)

創(chuàng)建了 array [1, 2, 3]。

或者,庫函數(shù) arrayOfNulls().

可以用于創(chuàng)建一個(gè)指定大小、元素都為空的數(shù)組。
另一個(gè)選項(xiàng)是用接受數(shù)組大小和一個(gè)函數(shù)參數(shù)的工廠函數(shù),用作參數(shù)的函數(shù)能夠返回 給定索引的每個(gè)元素初始值:

// 創(chuàng)建一個(gè) Array<String> 初始化為 ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })

如上所述,[] 運(yùn)算符代表調(diào)用成員函數(shù) get() 和 set()

Kotlin 也有無裝箱開銷的專門的類來表示原生類型數(shù)組:

ByteArray
ShortArray
IntArray

等等。

這些類和 Array并沒有繼承關(guān)系,但是 它們有同樣的方法屬性集。它們也都有相應(yīng)的工廠方法:

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

字符串

字符串用 String類型表示。字符串是不可變的。 字符串的元素——字符可以使用索引運(yùn)算符訪問:

 s[i]

可以用 for 循環(huán)迭代字符串:

for (c in str) { println(c)}

字符串模板

字符串可以包含模板表達(dá)式 ,即一些小段代碼,會(huì)求值并把結(jié)果合并到字符串中。 模板表達(dá)式以美元符($)開頭,由一個(gè)簡(jiǎn)單的名字構(gòu)成:

val i = 10
val s = "i = $i" // 求值結(jié)果為 "i = 10"

或者用花括號(hào)擴(kuò)起來的任意表達(dá)式:

val s = "abc"
val str = "$s.length is ${s.length}" // 求值結(jié)果為 "abc.length is 3"

原生字符串和轉(zhuǎn)義字符串內(nèi)部都支持模板。

基本類型

在Kotlin中,所有東西都是對(duì)象,所以我們可以調(diào)用成員函數(shù)和屬性的任何變量對(duì)象。有些類型是內(nèi)置的,他們的實(shí)現(xiàn)被優(yōu)化過, 但是用戶看起來他們就像普通的類. 本節(jié)我們會(huì)描述這些類型: numbers, characters, booleans 和 arrays.

Numbers

Kotlin處理numbers和Java很接近,但是并不完全相同. 例如, 對(duì)于numbers沒有隱式擴(kuò)大轉(zhuǎn)換(如java中int可以隱式變?yōu)閘ong),在一些情況下文字的使用有所不同.

對(duì)于numbers Kotlin提供了如下的內(nèi)置類型 (與Java很相近):

Type Bitwidth
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8

注意在kotlin中 characters 不是 numbers

字面量

下面是一些常量的寫法:

  • 十進(jìn)制: 123
    • Longs類型用大寫 L 標(biāo)記: 123L
  • 十六進(jìn)制: 0x0F
  • 二進(jìn)制: 0b00001011

注意: 不支持8進(jìn)制

Kotlin 同樣支持浮點(diǎn)數(shù)的常規(guī)表示方法:

  • Doubles 123.5, 123.5e10
  • Floats用 f 或者 F 標(biāo)記: 123.5f

存儲(chǔ)方式

在Java平臺(tái)數(shù)字是物理存儲(chǔ)為JVM的原始類型,除非我們需要一個(gè)可空的引用(例如int?)或泛型. 后者情況下數(shù)字被裝箱(指的是賦值的時(shí)候把實(shí)例復(fù)制了一下,不是相同實(shí)例)。

裝箱數(shù)字不會(huì)保存它的實(shí)例:

val a: Int = 10000
print(a identityEquals a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA identityEquals anotherBoxedA) // !!!Prints 'false'!!!

另一方面它們值相等:

val a: Int = 10000
print(a == a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA == anotherBoxedA) // Prints 'true'

顯示轉(zhuǎn)換

由于不同的存儲(chǔ)方式小的類型并不是大類型的子類型。
如果它們是的話,就會(huì)出現(xiàn)下述問題(下面的代碼不能通過編譯):

// Hypothetical code, does not actually compile:
val a: Int? = 1 // A boxed Int (java.lang.Integer)
val b: Long? = a // implicit conversion yields a boxed Long (java.lang.Long)
print(a == b) // Surprise! This prints "false" as Long's equals() check for other part to be Long as well

假設(shè)這樣是可以的,這里我們就悄無聲息的丟掉了一些數(shù)據(jù).

因此較小的類型不能隱式轉(zhuǎn)換為較大的類型。
因此我們不能聲明一個(gè) Byte 類型給一個(gè) Int 變量,在不進(jìn)行顯示轉(zhuǎn)換的情況下。

val b: Byte = 1 // OK, literals are checked statically
val i: Int = b // ERROR

我們可以顯示轉(zhuǎn)換的去擴(kuò)大類型

val i: Int = b.toInt() // OK: explicitly widened

每個(gè)number類型支持如下的轉(zhuǎn)換:

  • toByte(): Byte
  • toShort(): Short
  • toInt(): Int
  • toLong(): Long
  • toFloat(): Float
  • toDouble(): Double
  • toChar(): Char

失去隱式類型轉(zhuǎn)換,其實(shí)并沒有帶來多少困擾,因?yàn)槭褂米置媪康臅r(shí)候是沒有代價(jià)的,因?yàn)樽置媪康念愋褪峭茖?dǎo)出來的;
另一方面,算數(shù)運(yùn)算操作都針對(duì)不同類型的參數(shù)做好了重載,比如:

val l = 1.toLong() + 3 // Long + Int => Long

運(yùn)算符

Kotlin支持標(biāo)準(zhǔn)的算數(shù)操作符,并在相應(yīng)的類上定義為成員函數(shù)(但編譯器會(huì)針對(duì)運(yùn)算進(jìn)行優(yōu)化,將函數(shù)調(diào)用優(yōu)化成直接的算數(shù)操作)。
查看 Operator overloading.

對(duì)于按位操作(bitwise operation),沒有特別的符號(hào)來表示,而是直接使用命名函數(shù):

val x = (1 shl 2) and 0x000FF000

這是完整的位運(yùn)算操作 (只能對(duì) 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

Characters

Characters 用 Char來表示. 像對(duì)待numbers那樣就行

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

用單引號(hào)表示一個(gè)Character,例如: '1', '\n', '\uFF00'.
我們可以調(diào)用顯示轉(zhuǎn)換把Character轉(zhuǎn)換為Int

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

像numbers, characters是被裝箱當(dāng)使用一個(gè)可空的引用.這樣實(shí)例不會(huì)被保存。

Booleans

類型Boolean有兩個(gè)值: true{: .keyword } 和 false{: .keyword }.

Booleans使用nullable時(shí)候Boolean也會(huì)被裝箱.

內(nèi)置對(duì)Booelan的操作

  • || – 短路或
  • && – 短路與

數(shù)組

數(shù)組在Kotlin中使用 Array類來表示, Array類定義了set和get函數(shù)(使用時(shí)可以用[],通過符號(hào)重載的約定轉(zhuǎn)換), 和size等等一些有用的成員函數(shù):

class Array<T> private () {
  fun size(): Int
  fun get(index: Int): T
  fun set(index: Int, value: T): Unit

  fun iterator(): Iterator<T>
  // ...
}

我們可以使用庫函數(shù)array()來創(chuàng)建一個(gè)包含數(shù)值的數(shù)組, array(1, 2, 3) 創(chuàng)建了 array [1, 2, 3].
或者, arrayOfNulls()可以創(chuàng)建一個(gè)指定大小,元素都為空的數(shù)組。
或者使用函數(shù)來創(chuàng)建一個(gè)數(shù)組:

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

綜上, []操作符代表了成員函數(shù)get()set().

注意: 與Java不同的是, Kotlin中數(shù)組不可變. 這意味著我們不能聲明 Array<String>Array<Any>, 否則可能會(huì)產(chǎn)生一個(gè)運(yùn)行時(shí)錯(cuò)誤(但是你可以使用 Array<out Any>, 查看 Type Projections).

Kotlin有專門的類來表示原始類型的數(shù)組,避免了裝箱開銷: ByteArray,
ShortArray, IntArray 等等. 這些類和Array并沒有繼承關(guān)系,但是它們有同樣的方法屬性集. 它們也都有相應(yīng)的工廠方法:

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

字符串

字符串用String表示。字符串是不可變的。
字符串的原始字符可以使用操作符訪問: s[i].
字符串可以使用for{: .keyword }循環(huán)遍歷:

for (c in str) {
  println(c)
}

字符串字面量

Kotlin有兩種類型的字符串: 轉(zhuǎn)義字符串可能由轉(zhuǎn)義字符、原生字符串、換行和任意文本.轉(zhuǎn)義字符串很像java的String:

val s = "Hello, world!\n"

轉(zhuǎn)義方式采用傳統(tǒng)的反斜杠.

原生字符串使用三個(gè)引號(hào)(""")包括,內(nèi)部沒有轉(zhuǎn)義,可以包含換行和任何其他文本:

val text = """
  for (c in "foo")
    print(c)
"""

模板

字符串可以包含模板表達(dá)式,即一些小段代碼,會(huì)求值并把結(jié)果合并到字符串中。模板表達(dá)式以$符號(hào)開始,包含一個(gè)簡(jiǎn)單的名稱:

val i = 10
val s = "i = $i" // evaluates to "i = 10"

或者用花括號(hào)擴(kuò)起來,內(nèi)部可以是任意表達(dá)式:

val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"

Kotlin 開發(fā)者社區(qū)

國(guó)內(nèi)第一Kotlin 開發(fā)者社區(qū)公眾號(hào),主要分享、交流 Kotlin 編程語言、Spring Boot、Android、React.js/Node.js、函數(shù)式編程、編程思想等相關(guān)主題。

開發(fā)者社區(qū) QRCode.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容