從零開始學 Kotlin 之「2」數據類型

前言

大家好,這裏是「從零開始學 Kotlin 之『2 』數據類型」,本文首發於公衆號「Binguner」,歡迎前往大家關注。我會每週分享一些關於 Android 和其他方向的技術乾貨或一些關於認知的文章。學習一門技術最好的方式就是去教會別人,所以,開始今天的學習吧!

Kotlin 中的數據類型有基本數據類型應用類型

  • 基本數據類型值直接存在了變量
  • 應用類型的變量存儲的是類型所指對象的存儲地址

並且對於基本的數據類型(類似於 int,float 等),Kotlin 不會區分其是數據類型還是包裝類型,在運行的時候,數據會用最高效的方式顯示。

01 數字

Kotlin 提供了與 Java 類似的數字類型

類型 位寬度
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8

01 - 1 轉換函數

但是要注意:Kotlin 中沒有隱式轉換(就像 Java 中可以把 Int 轉換爲 Long),想要進行數字轉換,需要使用轉換函數

val a:Byte = 1
val b:Int = a  // 錯誤,編譯器會提示所需類型爲 Int,而提供的類型爲 Byte
val c:Int = a.toInt()  // 成功

每種數字類型都支持以下的數字轉換方法:

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

01 - 2 裝箱和拆箱

裝箱是指將基本數據類型轉換爲其對應的包裝器類型,
拆箱就是將包轉器類型轉換爲基本數據類型。

在 Java 中:

Integer x = 123;  // 是一個裝箱操作
int y = x;   // 是一個拆箱操作

而 Kotlin 中如何裝箱拆箱呢?

val i1 = 123  // 拆箱
val i2:Int? = 123 // 裝箱

想要了解其背後具體原理,可以自己動手將 Kotlin 代碼編譯成 Java 字節碼一探究竟。

02 字面常量

爲基本數據類型賦值的值稱爲字面常量。

Kotlin 中的字面常量有以下三種:

  • 十進制

類似:123,Long 類型的用大寫 L 標記:123L

  • 十六進制

類似:0x0F

  • 二進制

類似:0b00001011

另外,Kotlin 並不支持八進制。但卻默認支持 Double 和 Float。
例如:123.5,123.4e10,123f,123F 這些在 Kotlin 中都是支持的。

在聲明字面常量時,Kotlin 支持下劃線的聲明方式,使數字更加的易讀:

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

03 字符

Kotlin 中的字符使用 Char 表示,字符不能直接被當作數字來處理,必須通過 toInt() 方法被字符轉換爲數字類型

fun charToInt(c:Char):Int{
    return c.toInt()
}

Char 類的字面量用「' '」括起來,支持如下的轉義序列:

  • t
  • b
  • n
  • '
  • "
  • \
  • $

04 字符串

Kotlin 中的字符串和 Java 一樣用 String 申明,且不可變的。但是 Kotlin 中的字符串有一些新的特性。

04 - 1 新特性

  • 通過下標訪問字符串中的單個字符
val str = "Hello world!"
for (i in 0..str.length-1){
    print("${str[i]}_")
}  // 輸出 H_e_l_l_o_ _w_o_r_l_d_!_
  • 直接通過「+」操作符連接字符串
val s = "Hello" + '_'
println(s + "World")
// 輸出 Hello_World

04 - 2 字符串處理

  • 用 split() 分割字符串(split 函數的參數是一個 Regex 對象,寫好正則表達式後用 toRegex() 方法即可)
println("123_456_789".split("_".toRegex()))
// 輸出 [123, 456, 789]
  • 用其它方法分割字符串

    • substring() 從指定位置開始分割字符串,或者提取指定範圍的字符串
    • substringBefore() 分割掉指定位置之後的字符串
    • substringAfter() 分割掉指定位置之前的字符串
    • substringBeforeLast() 分割最後一個指定字符之後的字符串
    • substringAfterLast() 分割最後一個指定字符之前的字符串
val str = "Hello world!"
println("substring1: ${str.substring(5)}")
println("substring2: ${str.substring(0..4)}")
println("substring3: ${str.substring(6,12)}")
println("substringBefore: ${str.substringBefore(" ")}")
println("substringAfter: ${str.substringAfter(" ")}")
println("substringAfter: ${str.substringBeforeLast(" ")}")
println("substringAfterLast: ${str.substringAfterLast(" ")}")

// 運行結果:
substring1:  world!
substring2: Hello
substring3: world!
substringBefore: Hello
substringAfter: world!
substringAfter: Hello
substringAfterLast: world!

04 - 3 原始字符串

原始字符串用前後 3 個引號包圍

val rawStr =
        """
        The first line,
        the second line,
        the third line.
        """.trimIndent()  // 注意:如果「"""」所在行只有空格,這個方法會省略這些空白
    println(rawStr)
// 輸出:
The first line,
the second line,
the third line.

原始字符串通常還用 trimMargin() 處理,trimMargin() 的參數是一個邊界前綴字符串,默認的參數是「|」,例如下面的例子,每一行的開頭是「|」,那麼就會以每一行的「|」爲輸出的開頭進行字符輸出。

val rawStr = 
            """
            |   The first line,
        |the second line,
        |the third line.
    """.trimMargin("|")
// 輸出:
   The first line,
the second line,
the third line.

05 布爾類型

Kotlin 中的布爾類型用 Boolean 表示,它的值有 true 和 false。
若需要可空引用時,布爾類型的值會被裝箱。

它支持的運算有:

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

06 可空的基本數據類型

Kotlin 致力於消除 NullPointerException 帶來的影響。在 Java 中如果我們嘗試引用一個空的對象,就會導致空指針異常,但是在 Kotlin 中則不會。下面,我們來看看 Kotlin 是怎麼做到的。

Kotlin 對可空類型和非空類型做了區分,例如:「Int」不可空,「Int?」可空

var str :String? = null
println(str?.length)
// 輸出 null,而不是報空指針異常

在引用可空類型的時候,爲了避免空指針異常,Kotlin 要求必須進行非空檢查:

var str :String? = "Hellp"
// val length1 = str.length 這樣直接引用的時候,編譯器會報錯
//  Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
// 必須在可空類型上使用可空和非空斷言。
val length = str?.length  // 此時如果 str 爲空,運行返回 null
val length2 = str!!.length  // 此時如果 str 爲空,運行會拋出異常
// 或者進行類型檢查
val length3 = if(str != null) str.length else 0

07 Kotlin 中的一些其它類型

07 - 1 Any、Any?

Any 是 Kotlin 中所有非空類型的超類,相當於 Java 中的 Object。
可空類型的超類是 Any?

07 - 2 Unit

Unit 可以作爲函數的返回類型,表示沒有返回值或者返回值可以忽略。
注意 Unit 是一個類,並且繼承自 Any。

這是定義它的源代碼:

public object Unit {
    override fun toString() = "kotlin.Unit"
}

可以看到 Unit 是用 object 定義的單例類型,調用它的 toString() 方法,只會返回 「Kotlin.Unit」。

並且 Unit 的返回類型會返回 Unit 類型!!!

fun test(){}
val t = test()
println(t::class.java)
// 輸出 class kotlin.Unit

07 - 3 Nothing

Kotlin 中函數返回類型如果用 Nothing 表示,則這個函數永遠不會返回任何類型。

一些測試函數不會返回任何類型,就需要聲明返回類型爲 Nothing,它們通常拋出異常來結束運行。

fun test(msg:String):Nothing{
    throw IllegalStateException(msg)
}

test("test")
// 此時程序會拋出異常:Exception in thread "main" java.lang.IllegalStateException: test

最後

「從零開始學 Kotlin 之『2』數據類型」到這裏就結束了。

一下記住這麼多知識點有些困難,所以爲了方便大家的記憶與複習,我做了一張思維導圖放到下面,大家可以把圖片保存下來,有時間便去回顧學到的東西。

從零開始學 Kotlin 之「2」數據類型

推薦閱讀:

歡迎關注本文作者,這個系列的文章會首發在這裏:

掃碼關注 + 回覆「kotlin」,獲取我整理的最新版 Kotlin 學習視頻。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章