前言
自從Google把Kotlin語言作爲Android開發的官方開發語言後,越來越多的人開始用Kotlin替代Java來進行Android開發。前段時間看見郭神寫了個PermissiionX的庫,竟然當時也只支持Kotlin,這越發肯定了我學習Kotlin的決心。
環境搭建
最新的Android Studio(文章下面都簡稱AS)穩定版4.0已經自帶了Kotlin環境,所以這一步就省略,只需要將AS升級到最新版本就可以了。如果你還沒有下載AS,請戳AS最新版下載鏈接。
基本類型
在 Kotlin 中,所有東西都是對象,在這個意義上講我們可以在任何變量上調用成員函數與屬性。在本節中,我們會描述 Kotlin 中使用的基本類型:數字(數值類型)、字符、布爾值、數組與字符串。
數值類型
Kotlin 的基本數值類型包括 Byte、Short、Int、Long、Float、Double 等,這些基本數值類型就類似於Java當中的基本類型裝箱。不同於 Java 的是,字符不屬於數值類型,是一個獨立的數據類型。
整數類型
類型 | 大小(比特數) | 最小值 | 最大值 |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 (-231) | 2,147,483,647 (231 - 1) |
Long | 64 | -9,223,372,036,854,775,808 (-263) | 9,223,372,036,854,775,807 (263 - 1) |
所有未超出 Int 最大值的整型值初始化的變量都會推斷爲 Int 類型。如果初始值超過了其最大值,那麼推斷爲 Long 類型。 如需顯式指定 Long 型值,請在該值後追加 L 後綴。
val one = 1 // 推斷爲Int
val threeBillion = 3000000000 // 初始值超過Int最大值,推斷爲Long
val oneLong = 1L // Long
val oneByte: Byte = 1
浮點類型
Kotlin 提供了 Float 與 Double 類型。 根據 IEEE 754 標準, 兩種浮點類型的十進制位數(即可以存儲多少位十進制數)不同。 Float 反映了 IEEE 754 單精度,而 Double 提供了雙精度。
類型 | 大小(比特數) | 有效數字比特數 | 指數比特數 | 十進制位數 |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
對於以小數初始化的變量,編譯器會推斷爲 Double 類型。 如需將一個值顯式指定爲 Float 類型,請添加 f 或 F 後綴。 如果這樣的值包含多於 6~7 位十進制數,那麼會將其舍入。
val pi = 3.14 // Double
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float,實際值爲 2.7182817
字面常量
下面是所有類型的字面常量:
- 十進制:123
- 長整型以大寫的 L 結尾:123L
- 16 進制以 0x 開頭:0x0F
- 2 進制以 0b 開頭:0b00001011
- 注意:8進制不支持
Kotlin 同時也支持傳統符號表示的浮點數值:
- Doubles 默認寫法: 123.5, 123.5e10
- Floats 使用 f 或者 F 後綴:123.5f
你可以使用下劃線使數字常量更易讀:
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
數字比較
Kotlin 中沒有基礎數據類型,只有封裝的數字類型,你每定義的一個變量,其實 Kotlin 幫你封裝了一個對象,這樣可以保證不會出現空指針。數字類型也一樣,所以在比較兩個數字的時候,就有比較數據大小和比較兩個對象是否相同的區別了。
在 Kotlin 中,三個等號 === 表示比較對象地址,兩個 == 表示比較兩個值大小。
fun main(args: Array<String>) {
val a: Int = 10000
println(a === a) // true,值相等,對象地址相等
//經過了裝箱,創建了兩個不同的對象
val boxedA: Int? = a
val anotherBoxedA: Int? = a
//雖然經過了裝箱,但是值是相等的,都是10000
println(boxedA === anotherBoxedA) // false,值相等,對象地址不一樣
println(boxedA == anotherBoxedA) // true,值相等
}
類型轉換
由於不同的表示方式,較小類型並不是較大類型的子類型,較小的類型不能隱式轉換爲較大的類型。 這意味着在不進行顯式轉換的情況下我們不能把 Byte 型值賦給一個 Int 變量。Kotlin每種數據類型都有下面的這些方法,可以轉化爲其它的類型:
- toByte(): Byte
- toShort(): Short
- toInt(): Int
- toLong(): Long
- toFloat(): Float
- toDouble(): Double
- toChar(): Char
有些情況下也是可以使用自動類型轉化的,前提是可以根據上下文環境推斷出正確的數據類型而且數學操作符會做相應的重載。例如下面是正確的:
val l = 1L + 3 // Long + Int => Long
位運算
這個平常開發中可能相對用的少點,但是既然是學習,那我們一起也坐下筆記。
對於位運算,沒有特殊字符來表示,而只可用中綴方式調用具名函數
運算符 | 表示含義 | 對應Java |
---|---|---|
and(bits) | 按位與 | & |
or(bits) | 按位或 | | |
inv(bits) | 按位非 | ~ |
xor(bits) | 按位異或 | ^ |
shl(bits) | 有符號左移 | << |
shr(bits) | 有符號右移 | >> |
ushr(bits) | 無符號右移 | >>> |
下面看下示例
val a1 = 60
val b1 = 13
var c1 = -5
// 與
println(a1 and b1) //結果12
// 或
println(a1 or b1) //結果61
// 異或
println(a1 xor b1) //結果49
// 按位取反
println(a1.inv()) //結果-61
// 左移
println(a1.shl(1)) //結果120
// 右移
println(a1.shr(1)) //結果30
// 無符號右移
println(a1.ushr(1)) //結果30
字符
和 Java 不一樣,Kotlin 中的 Char 不能直接和數字操作,Char 必需是單引號 ’ 包含起來的。比如普通字符 ‘0’,‘a’。
fun check(c: Char) {
if (c == 1) { // 錯誤:類型不兼容
// ……
}
}
字符字面值用單引號括起來: ‘1’。 特殊字符可以用反斜槓轉義。 支持這幾個轉義序列:\t、 \b、\n、\r、’、"、\ 和 $。 編碼其他字符要用 Unicode 轉義序列語法:’\uFF00’。
我們可以顯式把字符轉換爲 Int 數字:
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 顯式轉換爲數字
}
布爾
布爾用 Boolean 類型表示,它有兩個值:true 和 false。
若需要可空引用布爾會被裝箱。
內置的布爾運算有:
- || 短路邏輯或
- && 短路邏輯與
- ! 邏輯非
數組
數組用類 Array 實現,並且還有一個 size 屬性及 get 和 set 方法,由於使用 [] 重載了 get 和 set 方法,所以我們可以通過下標很方便的獲取或者設置數組對應位置的值。
數組的創建兩種方式:一種是使用函數arrayOf();另外一種是使用工廠函數。如下所示,我們分別是兩種方式創建了兩個數組:
fun main(args: Array<String>) {
//[1,2,3]
val a = arrayOf(1, 2, 3)
//[0,2,4]
val b = Array(3, { i -> (i * 2) })
//讀取數組內容
println(a[0]) // 輸出結果:1
println(b[1]) // 輸出結果:2
}
如上所述,[] 運算符代表調用成員函數 get() 和 set()。
注意: 與 Java 不同的是,Kotlin 中數組是不型變的(invariant)。
除了類Array,還有ByteArray, ShortArray, IntArray,用來表示各個類型的數組,省去了裝箱操作,因此效率更高,其用法同Array一樣:
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串
和 Java 一樣,String 是不可變的。方括號 [] 語法可以很方便的獲取字符串中的某個字符,比如字符串str的元素字符可以使用索引運算符訪問: str[i],也可以通過 for 循環來遍歷:
for (c in str) {
println(c)
}
Kotlin 支持三個引號 “”" 擴起來的字符串,支持多行字符串,比如:
...
val text = """
多行字符串
多行字符串
"""
println(text) // 輸出有一些前置空格
...
但是通過你可以通過String類的庫函數 trimMargin() 方法來刪除多餘的空白。
可以用 + 操作符連接字符串。這也適用於連接字符串與其他類型的值, 只要表達式中的第一個元素是字符串:
val s = "abc" + 1
println(s + "def")
請注意,在大多數情況下,優先使用字符串模板或原始字符串而不是字符串連接。
字符串模板
字符串字面值可以包含模板表達式 ,即一些小段代碼,會求值並把結果合併到字符串中。 模板表達式以美元符($)開頭,由一個簡單的名字構成:
val i = 10
println("i = $i") // 輸出“i = 10”
或者用花括號括起來的任意表達式:
val s = "abc"
println("$s.length is ${s.length}") // 輸出“abc.length is 3”
原始字符串與轉義字符串內部都支持模板。 如果你需要在原始字符串中表示字面值 $ 字符(它不支持反斜槓轉義),你可以用下列語法:
val price = """
${'$'}9.99
"""
尾巴
今天的學習筆記就先到這裏了,下一篇我們將學習Kotlin中的基本語法。
老規矩,喜歡我的文章,歡迎素質三連:點贊,評論,關注,謝謝大家!