天天看點

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

Kotlin中的基本資料類型

作為Google【官方指定的幹兒子】,Kotlin語言今年受到了越來越多的重視。無論是開發Android還是背景程式,這門語言以後一定是大有可為。由于相關的文章很多,那我們不多介紹這門語言是怎麼來的。就讓我們慢慢來,一點一點的去品味Kotlin。

第一章,一起來看看這門語言的基本資料類型吧。

開始之前,我們需要明确一點:

kotlin是一門【強類型】、【靜态類型】、【支援隐式類型】的【顯式】類型語言。

PS:

1、強類型:強類型語言的編譯器引入了較多的類型檢查限制,是以在運作時不會發生未經明确(顯示轉換)類型轉換的類型轉換。常見的語言中,Java就是強類型語言,而JavaScript則是弱類型語言。

2、靜态類型:根據類型檢查在編譯時期還是運作時期,我們把語言分為靜态類型以及動态類型。靜态語言是基于編譯器來確定語言類型的安全。

3、顯式類型:根據變量名是否需要顯式的給出聲明,我們可以将語言分為顯式類型以及隐式類型。kotlin是顯式類型的語言,與此同時又因為有【類型推斷】的作用是以可以看做是支援隐式類型。

一、簡述

1、var 與 val

kotlin中,var符号表示的事變量,可以多次重複指派。

而val表示的是“常量”,但這并不是通俗意義上的常量。本質上val也是變量,但一次指派之後,不能再次修改,隻能作為【隻讀變量】。

2、kotlin中的根類型:Any

kotlin中萬物皆對象,所有類型都是引用類型。所有的類都有一個超類:Any。

官方文檔是這麼說的:

這個類隻有三個方法:

public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String           

如果類聲明中,沒有指明超類,則預設為Any。

kotlin中的Any映射為java中的java.lang.Object.

特别注意的一點:java中Object隻是所有引用類型的超類,而基本類型int、long等不包含在内。而kotlin中,Any是一切的超類。

3、kotlin中的數字類型

3.1、常識介紹

kotlin中常見的數字類型分為以下6種:

方法名 轉換類型 補充
Byte 8位 1位元組
Short 16位 2位元組
Int 32位 4位元組
Long 64位 8位元組
Float 32位 4位元組
Double 64位 8位元組

根據名稱可以看出基本和java中的相關定義相近。

kotlin支援二進制、十進制、十六進制;

但【不】支援八進制

與此同時,kotlin在數值類型的表示方式上也支援下劃線,如:

val Million = 1000_000_000

val tmp = 123_456_789L

val demo = 0xDD_FF_EE

kotlin中的數字類型與java很是相近,但有一點不同:

kotlin沒有java語言的隐式變換(如byte->short->int->long 等)。

是以,java中的如下代碼,在kotlin中是無法編譯的:

short a = 1;
int b = a;           

當然,在kotlin中應該這樣描述:

val a : Int = 1
val b : Long = a           
上述代碼同樣是無法通過編譯的!

是以,遇到類型轉換我們就應該考慮一下【顯式轉換】:

java中,我們一般會這樣進行數值類型的顯式轉換:

int a = 1;
...
Long tmp = (long)a;           

而kotlin中,我們可以這樣:

val a : Int = 1
val b : a.toLong()           

相關的方法彙總如下:

方法名 轉換類型
toByte() Byte
toShort() Short
toInt() Int
toLong() Long
toFloat() Float
toDouble() Double
toChar() Char

這裡需要注意一點的是:

與java不同,kotlin中Char類型僅僅表示字元,不能再被直接當做數字。 是以,Char類型的變量必須在單引号之間表示:’變量’。(CSDN部落格這裡顯示有誤。。。)

一段簡單的java代碼如下:

char a = 'c';
System.out.println(a+1);           

此時列印的結果為【數字】100。

而作為對比,在kotlin中:

val a : Char = 'c'
println(a+1)           

上述代碼的列印結果為【字元】d

是以我們要明确:Kotlin中 Char類型由于不是直接當數值用,是以最後傳回依舊是Char型。

3.2、一些需要注意的點

3.2.1、== 與 ===

kotlin中并沒有單純的數值,在我們定義每一個數值的時候,kotlin編譯器都在默默的為我們将定義的數值封裝成一個對象,以最大限度的解決空指針異常的問題。是以kotlin中數值的比較除了我們常見的 == 号之外還多了 === 。

當然,根據面向對象的定義也可以快速的了解:

符号名 作用 否定形式
== 【結構相等】比較兩個具體的【數值的大小】是否相同 !=
=== 【引用相等】比較兩個對象【在記憶體的存儲位址】是否相同 !==

ps:

編譯器中,== 等同于equal()方法。

舉個栗子來看:

fun main(args: Array<String>){
    val a : Int = 10
    println(a === a) //此處傳回的值為true
    val b : Int = a
    println(a === b) //此處傳回的值為true,因為指派操作是記憶體位址指派,而記憶體位址相同,其中的數字值自然相同
    println(a == b) //此處傳回的值為true,原因同上

}           

【☆☆☆】考慮到裝箱問題:數字裝箱不保留【同一性】,但保留數值的【相等性】。

val a: Int = 200
    println(a === a) //此處傳回的值為true
    val b :Int ? = a
    println(a === b) //此處傳回的值為false,因為這是兩個對象,記憶體位址不相同
    println(a == b) //此處傳回的值為true,數值相同           

當然還有一個特殊情況,考慮到JVM虛拟機的常量池特性:

val a: Int = 20
    println(a === a) //此處傳回的值為true
    val b :Int ? = 20
    println(a === b) //此處傳回的值為true
    println(a == b) //此處傳回的值為true,數值相同           

PS:

【1】JVM虛拟機中維護着有符号整形常量池(-128,127),在這個範圍裡的數值都會直接使用常量池的記憶體位址,是以這個範圍内的數值裝箱後比較記憶體位址依舊是相等的。(常量池主要用于存放兩大類常量:字面量(Literal)和符号引用量(Symbolic References))

【2】kotlin中,?表示這個對象可能為空。是以這一句“val b :Int ? = a”

表示的意思除了普通的數字指派外,還多了一層含義:如果被指派對象為空,則開辟記憶體建立新的對象。

3.2.2、移位操作

在java中,移位操作的表示非常簡潔,直接用符号即可表示:

符号名稱 作用
<< 左移位操作
*>> 右移位操作(此處*為顯示效果)
*>>> 無符号右移位

而在kotlin中,則沒有這些簡單的符号表示,取而代之的是相應的移位操作方法:

符号名稱 作用
shl(bits) 左移位
shr(bits) 右移位
ushr(bits) 無符号右移位
and(bits) 與操作
or(bits) 或操作
xor(bits) 異或操作
inv() 反向操作
3.2.3、運算符 + 的重載

先來看一段代碼:

val a = 10L + 1           

很明顯,上述代碼中,+ 左右兩個數分别為Long類型與Int類型。

那麼問題來了,我們前面說過,kotlin中并不支援數字類型的隐式轉換,而且上面表達式中的數字1并沒有顯示拓寬為Long類型,為何卻準确無誤呢???

答案很簡答,那就是kotlin中對于符号“+”的重載。

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

看一看到,源碼中有很多重載的方法。

當我們執行:val a = 10L + 1

實質上是:

val a = 10L.plus(1)

值得注意的一點是:XX.plus()方法中傳入的形參隻能為數值類型!

4、kotlin中的字元類型

kotlin中的基本字元為Char類型,相關的知識點我們已經在前文讨論過。

5、kotlin中的布爾類型

布爾用 Boolean 類型表示,它有兩個值:true 和 false。

若需要可空引用布爾會被裝箱。

6、kotlin中的字元串類型

kotlin中字元串是String類型。

與java類似,kotlin中的String同樣是由final修飾的,即不可被繼承。我們一起來看一些新的特性。

6.1、支援多行字元串

val string = """
            line 1
            line 2
            lin3 4
            """           

注意以上代碼的列印結果是存在前置的空格号的:

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

我們可以借助與 trimMargin() 發放做到去除掉每行的前置空格。

val string = """
            |line 1
            |line 2
            |lin3 4
            """.trimMargin("|")           

這裡有一點需要注意:trimMargin()方法需要傳入一個String類型的參數作為删除前置空格并進行每行分割的标志Flag,我們在這裡選用了”|”。

6.2、支援字元串模闆

在kotlin中,字元串可以包含字元串模闆用來表示前面用的到的一段代碼。kotlin中規定,所有的字元串模闆必須以美元符号”$”開頭。

val a = "temp"
 val q = "$a.length():"
 println(q+a.length)           

列印結果為:

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

原生字元串和轉義字元串内部都支援模闆。

6.3、索引運算符s[i]

當我們需要對一個字元串的某一位取值時,java中會用到:

"abc".charAt(i);           

而在kotlin中,我們可以簡單的用索引運算符即可:

val s = "abc"
s[0]//結果為a           

6.4、for循環疊代字元串

for (s in "12345"){println(s)}           

列印結果:

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

7、kotlin中的數組類型

7.1、生成數組

kotlin中的數組不是new出來的而是用了别的表示方法:

【1】fun_1

val a = arrayOf(1,2,3) //1,2,3           

【2】fun_2 工廠函數

val b = Array(3, { i -> (i * 2) })//0,2,4           

7.2、數組的多類型表示

kotlin中的數組支援多類型:

val arr = arrayOf(1,2,true,"abc")
    for(c in arr){println(c)}           

上述代碼的列印結果為:

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

注意:在這裡kotlin編譯器自動将數組更新為java.lang.Object類型了。

一起學習Kotlin——Kotlin中的基本資料類型Kotlin中的基本資料類型

7.3、建立空數組

除此之外在建立空數組時,我們必須顯示地知名數組元素的類型:

val b = arrayOfNulls(10)//錯誤           
val b = arrayOfNulls<Int>(10)//正确           

7.4、數組轉換

注意:kotlin中數組不是形變的,即我們不能将Array指派給Array。

繼續閱讀