Kotlin基本類型

原文地址

Basic Types

在Kotlin中,在通過變量調(diào)用成員函數(shù)和屬性的意義上來講,任何東西都是對象。一些類型是嵌入的,由于他們的實(shí)現(xiàn)被優(yōu)化了,但是對于用戶他們看起來像普通的類。在本章中我們描述多數(shù)這種類型:如數(shù)字、字符、布爾和數(shù)組。

數(shù)字:

Kotlin處理數(shù)字的方式接近java,但不完全相同。例如,這兒沒有對數(shù)字隱性擴(kuò)展轉(zhuǎn)換,并且字面值在某些情況下也不一樣。

Kotlin提供如下嵌入類型代表數(shù)字(很像java)
Type Bit width
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8

注意在Kotlin中字符不是數(shù)字

Literal Constants(字面常量)

下面是幾種字面常量對于整數(shù):
  • 十進(jìn)制:123
  • 被大寫字母L標(biāo)記的長整形:123L
  • 16進(jìn)制:0x0F
  • 二進(jìn)制:0b00001011

注意:8進(jìn)制字面值是不支持的。

Kotlin也支持常規(guī)的符號對于浮點(diǎn)型:
  • Doubles by default(默認(rèn)Double型): 123.5, 123.5e10
  • Floats 被標(biāo)記為f或者F:123.5f

Underscores in numeric literals (since 1.1)(數(shù)字中的下劃線)

為了讓數(shù)字常量更易閱讀,你能夠使用下劃線

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Representation

在Java平臺中,數(shù)字被存為JVM原始類型,除非我們需要一個(gè)可空的數(shù)字引用(也就是Int?)或者涉及到泛型時(shí)。下面的情況當(dāng)中數(shù)字是被裝箱的。
注意,裝箱的數(shù)字不保留一致性

val a: Int = 10000
print(a === a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA === 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'

Explicit Conversions(顯示轉(zhuǎn)換)

由于不同表示,較小的類型不是較大類型的子類型。如果他們是,我們將在一些情況下有一些問題:

//假定代碼,并不實(shí)際編譯:
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

所以不僅一致性,甚至相等性也將會消失。
結(jié)果是,較小的類型不會隱式轉(zhuǎn)換為較大的類型。我們不能把一個(gè)Byte的值賦給一個(gè)Int變量在沒有明確的轉(zhuǎn)換的情況下。

val b: Byte = 1 // 成功,字面值被靜態(tài)的檢查
val i: Int = b // ERROR

我們可以使用顯示轉(zhuǎn)換去擴(kuò)大的數(shù)字

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

每個(gè)數(shù)字類型支持如下轉(zhuǎn)換:
? oByte(): Byte
? toShort(): Short
? toInt(): Int
? toLong(): Long
? toFloat(): Float
? toDouble(): Double
? toChar(): Char

隱式轉(zhuǎn)換的缺失很少被注意到因?yàn)樯舷挛闹械念愋屯茢?,和算術(shù)操作符被重載為合適的轉(zhuǎn)換,例如:

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

Operations

Kotlin支持被聲明為類成員的數(shù)字運(yùn)算的標(biāo)準(zhǔn)集。(但是編譯器優(yōu)化了相關(guān)的調(diào)用指令),參看操作符重載
作為位運(yùn)算,這里沒有特殊的字符,但是只有能夠以前綴方式調(diào)用的命名函數(shù),例如:

val x = (1 shl 2) and 0x000FF000

這兒有完整的未操作符(僅僅適用于整型和長整型)
? 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

字符

字符被Char類型表示,他們不能直接被當(dāng)做數(shù)字

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

字符文字在單引號中’1’.特殊字符能夠被轉(zhuǎn)義用反斜杠。如下轉(zhuǎn)義結(jié)果被支持:\t, \b, \n, \r, ', ", \ and $.為了編碼其他任何字符,適用Unicode轉(zhuǎn)義語法:'\uFF00'
我們可以明確的把一個(gè)字符轉(zhuǎn)為一個(gè)整型:

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

像數(shù)字那樣,字符被裝箱當(dāng)可空引用類型需要的時(shí)候。通過裝箱操作,一致性將不被保留。

布爾類型

Boolean類型代表布爾類型,并且有兩個(gè)值:true和false。
布爾類型被裝箱當(dāng)一個(gè)可空的引用被需要的時(shí)候。
嵌入操作當(dāng)布爾類型包括
? || – lazy disjunction
? && – lazy conjunction
? ! - negation

數(shù)組

Arrays 在Kotlin中代表有g(shù)et和set函數(shù)的類(轉(zhuǎn)化為[]通過操作符重載的約定),和size屬性,和一些其他有用的成員函數(shù)。

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

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

為了創(chuàng)建一個(gè)數(shù)組,我們可以使用一個(gè)庫函數(shù)arrayof()并且傳進(jìn)一些值進(jìn)去。所以arrayof(1,2,3)創(chuàng)建一個(gè)數(shù)組array[1,2,3].相反的,arrayofNulls()庫函數(shù)可以用于創(chuàng)建一個(gè)空數(shù)組

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

正如我之上所說的那樣,[]操作符代表調(diào)用成員函數(shù)get()和set();
注意:不像java,kotlin中的arrays是不變的。也就意味kotlin不允許我們分配一個(gè)Array<String>到Array<Any>,這阻止了一個(gè)運(yùn)行時(shí)異常(但是你可以使用Array<out Any>,參看Type Projections
Kotlin也有一些特殊的類代表沒有裝箱損耗的原始類型的數(shù)組:ByteArray,ShortArray,IntArray等等,這些類沒有Array類的相關(guān)繼承類,但是他們有相同的屬性和函數(shù)集合。他們中每一個(gè)也含有一個(gè)相應(yīng)的工廠函數(shù):

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

字符串

字符串代表類型String。字符串是不可變的。String中的元素是可以被索引操作訪問的字符:s[i]。一個(gè)字符串可以通過for循環(huán)遍歷

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

String 字面值

Kotlin有兩種類型的字符串字面值:轉(zhuǎn)義字符串可能含有轉(zhuǎn)義字符,原始字符串可以包含換行和任意文本。一個(gè)轉(zhuǎn)義字符串非常像java字符串。

Val s= “Hello,World!\n”

轉(zhuǎn)義是像傳統(tǒng)方式那樣完成的,通過反斜杠。參看之上的Characters,支持的轉(zhuǎn)義序列列表

一個(gè)原始字符串被一個(gè)引用(“””)限定,包含非轉(zhuǎn)義和能夠包含換行和其他任意字符串。

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

你可以移除開頭空格通過trimMargin()函數(shù):

val text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin()

默認(rèn)情況下| 用于頁邊前綴,但是你能夠選擇另一個(gè)字符串并且把它當(dāng)做參數(shù)傳入,例如trimMargin(">").

字符串模板

字符串可能包含模板表達(dá)式,也就是被評估的代碼碎片和結(jié)果被嵌入到字符串中。一個(gè)模板表達(dá)式可以以美元符號開始并且包含一個(gè)簡單的名稱:

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

或者一個(gè)在花括號中的任意表達(dá)式:

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

模板同時(shí)被原始字符串和轉(zhuǎn)義字符串支持。如果你需要表示一個(gè)字面值$字符在原始字符串中(不支持反斜杠轉(zhuǎn)義),你可以使用如下語法:

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

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

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