Kotlin 基本數(shù)據(jù)類型
從這篇文章開始,我們將深入學習 Kotlin 常見的幾大基本數(shù)據(jù)類型,比如整數(shù)類型、浮點數(shù)類型、字符類型、布爾類型等。在深入之前,會先從整體上認識下 Kotlin 類型系統(tǒng)的劃分,然后 Kotlin 中的基本類型充當其中什么角色,以及它和 Java 中基本數(shù)據(jù)類型有什么區(qū)別。
1. Kotlin 類型系統(tǒng)
在 Kotlin 中類型系統(tǒng)主要分為兩大類 : 基本類型和其他基本類型,但是需要注意的是與 Java 不同,Kotlin 并不區(qū)分基本數(shù)據(jù)類型和它的包裝類,然后基本數(shù)據(jù)類型還可以分為: 非空基本類型和可空基本類型。
在 Kotlin 中一切皆是對象,那么從某種意義上來說我們可以再任何變量對象上調用它的成員函數(shù)與屬性。而在 Java 中基本數(shù)據(jù)類型(int,double,long
等)不是一個類。在 Kotlin 中基本數(shù)據(jù)類型(Int,Double,Long
等)它們看起來更像是一個普通的類。所以它也不需要像 Java 的 int
一樣有對應的包裝器類 Integer
,Kotlin 的基本數(shù)據(jù)類型沒有對應的包裝器類。
上圖是 Kotlin 中的基本數(shù)據(jù)類型詳細劃分,下面我們來一一看下這幾種數(shù)據(jù)類型:
2. 數(shù)字類型
2.1 整數(shù)類型
Kotlin 中提供一組表示整數(shù)數(shù)字的內置類型,主要有四種,下面是一張表格表示它們各自取值范圍:
類型 | 大小(占用比特數(shù)) | 最小值 | 最大值 |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 | 2,147,483,647 |
Long | 64 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
val number = 100 //默認是 Int 類型
val bigNumber = 8000000000 //超過 Int 最大值默認是 Long 類型
val longNumber = 20L //數(shù)字后面顯式加L,表示聲明 Long 類型
val byteNumber: Byte = 1
Tips:所有未超出
Int
最大值的整型值初始化的變量都默認為Int
類型,如果初始值超過了其最大值,那么推斷為Long
類型。在數(shù)字值后面顯式添加L
表示一個Long
類型
2.2 浮點數(shù)類型
Kotlin 中提供了 Float
和 Double
兩種類型來分別表示單精度和雙精度的浮點數(shù)類型。
類型 | 大小(占用比特數(shù)) | 有效數(shù)字比特數(shù) | 指數(shù)比特數(shù) | 十進制位數(shù) |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
一起來看下幾個例子:
val pi = 3.1415926 //默是Double類型
val doubleNumber = 1.23343434343 //默認是Double類型
val floatNumber = 2.3423344378f//尾部加f或F顯式表示這是一個Float類型的浮點數(shù)
Kotlin 對于默認小數(shù)的推斷是Double
類型。如果需要顯式將一個小數(shù)指定為Float
類型需要在數(shù)值尾部加入f
或F
。由于Float
類型十進制位數(shù)是6~7
,所以上述例子中floatNumber
實際值大小為2.3423344
,后面就會出現(xiàn)進度丟失舍棄。
在 Kotlin 中還有一點與 Java 不同的是,Kotlin 中數(shù)字不存在隱式的拓寬轉換。比如一個函數(shù)參數(shù)為Double
的函數(shù)只能接收 Double
類型,不能接收 Float
、Int
或者其他數(shù)字類型。
2.3 數(shù)字常量
在 Kotlin 支持數(shù)字的十進制、二進制、十六進制的表示,但是注意 Kotlin 不支持八進制的表示。
進制表示 | 十進制 | 二進制 | 十六進制 |
---|---|---|---|
示例 | 100 | 0b00001001 | 0x0F |
在 Kotlin 為了使得數(shù)字常量更易可讀,可以使用下劃線將數(shù)字隔開。
val bigNumber = 3_000_000_000
val bytesNumber = 0b11010010_01101111_0001001_10001000
val hexNumber = 0xFF_EF_D7_3F
2.4 數(shù)字類型強制轉換
在 Kotlin 中與 Java 不同是通過調用 toInt、toDouble、toFloat
之類函數(shù)來實現(xiàn)數(shù)字類型的強制轉換的。
類型 | 強轉函數(shù) |
---|---|
Byte | toByte() |
Short | toShort() |
Int | toInt() |
Long | toLong() |
Float | toFloat() |
Double | toDouble() |
Char | toChar() |
缺乏隱式類型轉換很少會引起注意,因為類型會從上下文推斷出來,而算術運算會有重載做適當轉換,例如:
val number = 20L + 40 // Long + Int => Long
2.5 數(shù)字運算
2.5.1 四則運算
除法/
:
val number = 3 / 2
println(number) // 輸出 1
val floatNumber = 3 / 2.toDouble()
println(number) // 輸出 1.5
乘法*
:
val number = 3 * 2
println(number) // 輸出 6
加法+
:
val number = 3 + 2
println(number) // 輸出 5
減法-
:
val number = 3 - 2
println(number) // 輸出 1
取余%
:
val number = 3 % 2
println(number) // 輸出 1
2.5.2 位運算
Kotlin 中的位運算和 Java 不同的是沒有用特殊符號來表示,可以采用了中綴函數(shù)方式調用具名函數(shù)。
shl(bits)
– 有符號左移;shr(bits)
– 有符號右移;ushr(bits)
– 無符號右移;and(bits)
– 位與;or(bits)
– 位或;inv()
– 位非;xor(bits)
– 位異或。
val number = (3 shr 4) and 0x000EF000
3. 字符類型
在 Kotlin 中字符用 Char
類型表示。并且不能像 Java 一樣可以直接當作數(shù)字:
fun testChar(char: Char) {
if(char == 4) {...}//此處會提示類型不匹配的異常
}
字符的值用單引號括起來: '1'
。 特殊字符可以用反斜杠轉義。 支持這幾個轉義序列:\t
、 \b
、\n
、\r
、\'
、\"
、\\
與 \$
。 編碼其他字符要用 Unicode 轉義序列語法:'\uFF00'
。
雖然不能直接把它當作數(shù)字來用,但是我們可以通過decimalDigitValue
函數(shù)將字符轉換成數(shù)字,注意可空類型 Char?
類型會存在裝箱操作
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 顯式轉換為數(shù)字
}
4. 布爾類型
在 Kotlin 使用Boolean
表示布爾類型,它只有兩個值 true
和 false
。注意可空類型Boolean?
類型會存在裝箱操作。
val isVisible: Boolean = false
5. 數(shù)組類型
5.1 Array
數(shù)組
在 Kotlin 中數(shù)組使用Array
這個類來辨識,它定義了 get
與 set
函數(shù)(按照運算符重載約定這會轉變?yōu)?[]
)以及 size
屬性,以及一些其他有用的成員函數(shù):
public class Array<T> {
/**
* Creates a new array with the specified [size], where each element is calculated by calling the specified
* [init] function.
*
* The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index.
*/
public inline constructor(size: Int, init: (Int) -> T)
/**
* Returns the array element at the specified [index]. This method can be called using the
* index operator.
* ```
* value = arr[index]
* ```
*
* If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS
* where the behavior is unspecified.
*/
public operator fun get(index: Int): T
/**
* Sets the array element at the specified [index] to the specified [value]. This method can
* be called using the index operator.
* ```
* arr[index] = value
* ```
*
* If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS
* where the behavior is unspecified.
*/
public operator fun set(index: Int, value: T): Unit
/**
* Returns the number of elements in the array.
*/
public val size: Int
/**
* Creates an iterator for iterating over the elements of the array.
*/
public operator fun iterator(): Iterator<T>
}
我們可以使用庫函數(shù) arrayOf()
來創(chuàng)建一個數(shù)組并傳遞元素值給它,這樣 arrayOf(1, 2, 3)
創(chuàng)建了 array [1, 2, 3]
。 或者,庫函數(shù) arrayOfNulls()
可以用于創(chuàng)建一個指定大小的、所有元素都為空的數(shù)組。
另一個選項是用接受數(shù)組大小以及一個函數(shù)參數(shù)的 Array
構造函數(shù),用作參數(shù)的函數(shù)能夠返回給定索引的每個元素初始值:
//創(chuàng)建一個 Array<String> 初始化為 ["0", "1", "4", "9", "16", "25", "36", "49", "64", "81"]
val asc = Array(10) { i -> (i * i).toString() }
asc.forEach { println(it) }
5.2 原生類型數(shù)組
在Kotlin中也有無裝箱開銷的專門的類來表示原生類型數(shù)組: ByteArray
、 ShortArray
、IntArray
等等。這些類與 Array
并沒有繼承關系,但是它們有同樣的方法和屬性。
val intArray = intArrayOf(1, 2, 3, 4, 5)// 使用intArrayOf函數(shù)創(chuàng)建并初始化一個IntArray [1, 2, 3, 4, 5]
val intArr1 = IntArray(5) //創(chuàng)建一個長度為5的空的IntArray
val intArr2 = IntArray(5) { 100 } //創(chuàng)建一個長度為5的值全為100的IntArray [100, 100, 100, 100, 100]
val intArr3 = IntArray(5) { it * 2 } //注意這里it是它索引下標值,所以這是創(chuàng)建一個長度為5的IntArray [0, 2, 4, 6, 8]
6. 字符串類型
在 Kotlin 中字符串用 String
類型表示。字符串是不可變的。 字符串的元素——字符可以使用索引運算符訪問: s[i]
。 可以用 for 循環(huán)迭代字符串:
for(char in str) {
println(char)
}
和 Java 一樣,Kotlin 可以用 +
操作符連接字符串。這也適用于連接字符串與其他類型的值, 只要表達式中的第一個元素是字符串,但是 Kotlin 中有字符串模板,大部分情況下建議使用字符串模板來替代+
拼接字符串。
val age = 28
println("I am " + age + "years old!")
println("I am $age years old!")
6.1 字符串的值
Kotlin 有兩種類型的字符串字面值:轉義字符串可以有轉義字符, 以及原始字符串可以包含換行以及任意文本。以下是轉義字符串的一個示例:
val s = "Hello, world!\n"
轉義采用傳統(tǒng)的反斜杠方式。
字符串使用三個引號("""
)分界符括起來,內部沒有轉義并且可以包含換行以及任何其他字符:
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()
6.2 字符串模板
字符串字面值可以包含模板表達式 ,即一些小段代碼,會求值并把結果合并到字符串中。 模板表達式以美元符($
)開頭,由一個簡單的名字構成:
val number = 100
println("The Result is $number")
或者用花括號${}
括起來的任意表達式:
val text = "This is Text"
println("Text length is ${text.length}")
字符串與轉義字符串內部都支持模板。 如果你需要在原始字符串中表示字面值 $
字符(它不支持反斜杠轉義),你可以用下列語法:
val price = "${'$'}9.99"
7. 小結
到這里有關 Kotlin 基本類型就闡述完畢了,下一篇文章我們將進入Kotlin中的條件選擇、循環(huán)分支控制相關知識點。