Kotlin——初級篇(三):資料型別詳解

Jetictors發表於2019-03-04
Kotlin——初級篇(三):資料型別詳解

任意一種開發語言都有其資料型別,並且資料型別對於一門開發語言來說是最基本的構成,同時也是最基礎的語法。當然,Kotlin也不例外。Kotlin的資料型別和Java是大致相同的,但是他們的寫法不同,並且型別之間的轉換也存在著差異。下面為大家詳細說明並舉例。

目錄

Kotlin——初級篇(三):資料型別詳解

一、數值型別

1、Kotlin中的數字的內建型別(接近與Java),其關鍵字為:

  • Byte=> 位元組 => 8位
  • Short => 短整型 => 16位
  • Int => 整型 => 32位
  • Long => 長整型 => 64位
  • Float => 浮點型 => 32位
  • Double => 雙精度浮點型 => 64位

例:

var a: Byte = 2
var b: Short = 2
var c: Int = 2
var d: Long = 2L         //長整型由大寫字母L標記
var e: Float = 2f        //單精度浮點型由小寫字母f或大寫字元F標記
var f: Double = 2.0
println(" a => $a 
 b => $b 
 c => $c 
 d => $d 
 e => $e 
 f => $f);   
複製程式碼

輸出結果為:

a => 2 
b => 2 
c => 2 
d => 2 
e => 2.0 
f => 2.0 
複製程式碼

2、進位制數

  • 二進位制數
  • 八進位制數(Kotlin不支援)
  • 十進位制數
  • 十六進位制數

例:

var g = 0x0F            //十六進位制數
var h = 0b00001011      //二進位制數
var k = 123             //十進位制數
// ps:Kotlin不支援八進位制數
println(" g => $g 
 h => $h 
 k => $k);   
複製程式碼

輸出結果為:

g => 15 
h => 11 
k => 123 
複製程式碼

3、數字型別字面常量的下劃線

作用:分割數字進行分組,使數字常量更易讀

例:

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

println("oneMillion => $oneMillion")
println("creditCardNumber => $creditCardNumber")
println("socialSecurityNumber => $socialSecurityNumber")
println("hexBytes => $hexBytes")
println("bytes => $bytes")
複製程式碼

輸出結果為:

oneMillion => 1000000
creditCardNumber => 1234567890123456
socialSecurityNumber => 999999999
hexBytes => 4293713502
bytes => 3530134674
複製程式碼

4、裝箱與拆箱

  • 裝箱與拆箱
  • Kotlin中,存在數字的裝箱,但是不存在拆箱。因為Kotlin是沒有基本資料型別的,Kotlin是萬般皆物件的原則。故不存在和Java中的類似int是資料型別,Integer是整型的引用型別。

Kotlin中要實現裝箱操作。首先要了解可空引用。即類似Int?(只限數值型別)這樣的。

例:

val numValue: Int = 123
//裝箱的過程,其實裝箱之後其值是沒有變化的
val numValueBox: Int? = numValue
println("裝箱後: numValueBox => $numValueBox")
複製程式碼

輸出結果為:

裝箱後: numValueBox => 123
複製程式碼
  • 兩個數值的比較

判斷兩個數值是否相等(==),判斷兩個數值在記憶體中的地址是否相等(===),其實上面的裝箱操作之後其記憶體中的地址根據其資料型別的數值範圍而定。

例:

val numValue: Int = 128    
val numValueBox: Int? = numValue

/*
    比較兩個數字
 */
var result: Boolean
result = numValue == numValueBox
println("numValue == numValueBox => $result")  // => true,其值是相等的

result = numValue === numValueBox
/*
  上面定義的變數是Int型別,大於127其記憶體地址不同,反之則相同。
  這是`kotlin`的快取策略導致的,而快取的範圍是` -128 ~ 127 `。
  故,下面的列印為false
*/
println("numValue === numValueBox => $result")  
複製程式碼

輸出結果為:

numValue == numValueBox => true
numValue === numValueBox => false
複製程式碼

Ps:各位可以試試將變數numValue的值改為在-128 ~ 127這個區間的數字試試

5、轉換

  • 顯式轉換
  • 較小的型別不會被隱式轉換為更大的型別,故而系統提供了顯式轉換。提供的顯式轉換方法如下:
    1. toByte() => 轉換為位元組型
    2. toShort() => 轉換為短整型
    3. toInt() => 轉換為整型
    4. toLong() => 轉換為長整型
    5. toFloat() => 轉換為浮點型
    6. toDouble() => 轉換為雙精度浮點型
    7. toChar() => 轉換為字元型
    8. toString() => 轉換為字串型

例:

var numA: Int = 97
println(numA.toByte())
println(numA.toShort())
println(numA.toInt())
println(numA.toLong())
println(numA.toFloat())
println(numA.toDouble())
println(numA.toChar())
println(numA.toString())
複製程式碼

輸出結果為:

97
97
97
97.0
97.0
97
a
97
複製程式碼
  • 隱式轉換

型別是從上下文推斷出來的,即算術運算則被過載為適當的轉換

例:

// 30L + 12 -> Long + Int => Long
val num = 30L + 12
print(num)
複製程式碼

輸出結果為:

42
複製程式碼

6、位運算子

  • Kotlin中對於按位操作,和Java是有很大的差別的。Kotlin中沒有特殊的字元,但是隻能命名為可以以中綴形式呼叫的函式,下列是按位操作的完整列表(僅適用於整形(Int)和長整形(Long):
    1. shl(bits) => 有符號向左移 (類似Java<<)
    2. shr(bits) => 有符號向右移 (類似Java>>)
    3. ushr(bits) => 無符號向右移 (類似Java>>>)
    4. and(bits) => 位運算子 and (同Java中的按位與)
    5. or(bits) => 位運算子 or (同Java中的按位或)
    6. xor(bits) => 位運算子 xor (同Java中的按位異或)
    7. inv() => 位運算子 按位取反 (同Java中的按位取反)

下面附上Kotlin中關於位操作符的原始碼:

/** Shifts this value left by [bits]. */
public infix fun shl(bitCount: Int): Int
/** Shifts this value right by [bits], filling the leftmost bits with copies of the sign bit. */
public infix fun shr(bitCount: Int): Int
/** Shifts this value right by [bits], filling the leftmost bits with zeros. */
public infix fun ushr(bitCount: Int): Int
/** Performs a bitwise AND operation between the two values. */
public infix fun and(other: Int): Int
/** Performs a bitwise OR operation between the two values. */
public infix fun or(other: Int): Int
/** Performs a bitwise XOR operation between the two values. */
public infix fun xor(other: Int): Int
/** Inverts the bits in this value. */
public fun inv(): Int
複製程式碼

例:

 /*
    位運算子
    支援序列如下:shl、shr、ushr、and、or、xor、inv
 */
var operaNum: Int = 4

var shlOperaNum = operaNum shl(2)
var shrOperaNum = operaNum shr(2)
var ushrOperaNum = operaNum ushr(2)
var andOperaNum = operaNum and(2)
var orOperaNum = operaNum or(2)
var xorOperaNum = operaNum xor(2)
var invOperaNum = operaNum.inv()

println("shlOperaNum => $shlOperaNum 
 " +
        "shrOperaNum => $shrOperaNum 
 " +
        "ushrOperaNum => $ushrOperaNum 
 " +
        "andOperaNum => $andOperaNum 
 " +
        "orOperaNum => $orOperaNum 
 " +
        "xorOperaNum => $xorOperaNum 
 " +
        "invOperaNum => $invOperaNum")
複製程式碼

輸出結果為:

shlOperaNum => 16 
shrOperaNum => 1 
ushrOperaNum => 1 
andOperaNum => 0 
orOperaNum => 6 
xorOperaNum => 6 
invOperaNum => -5 
複製程式碼

二、布林型別(Boolean)

1、關鍵字

Boolean關鍵字表示布林型別,並且其值有truefalse

例:

var isNum: Boolean
isNum = false
println("isNum => $isNum")
複製程式碼

輸出結果為:

isNum => false
複製程式碼

2、邏輯操作符(與Java相同)

  • ` || ` => 邏輯或(或者)
  • ` && ` => 邏輯與(並且)
  • ` ! ` => 邏輯非(取反)

例:

/*
    操作運算子
    ` || ` => 邏輯或(或者)
    ` && ` => 邏輯與(並且)
    ` ! ` => 邏輯非(取反)
 */
var a: Boolean = false
var b: Boolean = true
var result: Boolean

/* 邏輯或操作 */
if (a || b){
    result = a || b
    println("a || b => $result")
}

/* 邏輯與操作 */
if (a && b){
    result = a && b
    println("a && b => $result")
}

/* 邏輯非操作 */
result = !a
println("!a => $result")

result = !b
println("!b => $result")
複製程式碼

輸出結果為:

isNum => false
a || b => true
!a => true
!b => false
複製程式碼

三、字元型(Char)

1、關鍵字

Char為表示字元型,字元變數用單引號(‘ ’)表示。並且不能直接視為數字,不過可以顯式轉換為數字。

例:

var char1: Char
char = `a`
//char1 = 1        => 這句程式碼會直接出錯
println("char1 => $char1")
複製程式碼

輸出結果為:

char1 => a
複製程式碼

2、顯示轉換為其他型別

字元型的變數不僅可以轉換為數字,同時也可轉換為其他型別

例:

var var1 = char1.toByte()
var var2 = char1.toInt()
var var3 = char1.toString()
var var4 = char1.toFloat()
var var5 = char1.toShort()
println("var1 => $var1 
 var2 => $var2 
 var3 => $var3 
 var4 => $var4 
 var5 => $var5")
複製程式碼

輸出結果為:

var1 => 97 
var2 => 97 
var3 => a 
var4 => 97.0 
var5 => 97
複製程式碼

PS:除了可以轉換型別外,當變數為英文字母時還支援大小寫轉換。

例:

/*
   當字元變數為英文字母時,大小寫的轉換
*/
var charA: Char = `a`
var charB: Char = `B`
var charNum: Char = `1`
var result: Char

// 轉換為大寫
result = charA.toUpperCase() 
println("result => $result")

// 轉換為小寫
result = charB.toLowerCase()
println("result => $result")

//當字元變數不為英文字母時,轉換無效
result = charNum.toLowerCase()
println("result => $result")
複製程式碼

輸出結果為:

result => A
result => b
result => 1
複製程式碼

3、字元轉義
Java一樣,使用某些特殊的字元時,要使用轉義。下列是支援的轉義序列:

  • => 表示製表符

  • => 表示換行符
  • => 表示退格鍵(鍵盤上的Back建)

  • => 表示鍵盤上的Enter
  • \ => 表示反斜槓
  • ` => 表示單引號
  • " => 表示雙引號
  • $ => 表示美元符號,如果不轉義在kotlin中就表示變數的引用了
  • 其他的任何字元請使用Unicode轉義序列語法。例:`uFF00`

例:

println("
  換行符")
println("	  製表符")
println("   退格鍵")
println("
  Enter鍵同樣換行")
println(`\`)
println(```)
println(`"`)
println(`$`)
println(`uFF01`)
複製程式碼

輸出結果為:


 換行符
     製表符

 退格鍵
 Enter鍵同樣換行

`
"
$
!
複製程式碼

四、字串型別(String)

1、關鍵字

String表示字串型別。其是不可變的。所以字串的元素可以通過索引操作的字元:str[index]來訪問。可以使用for迴圈迭代字串:
其中str[index]中的str為要目標字串,index為索引

例:

val str: String = "kotlin"
println("str => $str")

//迭代
for (s in str){
    print(s)
    print("	")
}
複製程式碼

輸出結果為:

str => kotlin
k	o	t	l	i	n	
複製程式碼

2、 字串字面量

Kotlin中, 字串字面量有兩種型別:

  • 包含轉義字元的字串 轉義包括(
    等),不包含轉義字串的也同屬此型別
  • 包含任意字元的字串 由三重引號(""" .... """)表示

例:

// 型別1:
var str1: String = "hello		kotlin"
println(str1)
str1 = "hello kotlin"
println(str1)

// 型別2:
val str2 = """ fun main(args: Array<String>){
    println("我是三重引號引用的字串,我可以包含任意字元")
    } """
println(str2)
複製程式碼

輸出結果為:

hello		kotlin
hello kotlin
fun main(args: Array<String>){
    println("我是三重引號引用的字串,我可以包含任意字元")
    } 
複製程式碼

PS: 可以使用trimMargin()函式刪除前導空格 ,預設使用符號(|)作為距字首,當然也可以使用其他字元。例:右尖括號(>)、左尖括號(<)等。

例:

val str3: String = """
    > I`m like Kotlin .
    > I`m like Java .
    > I`m like Android .
    > I`m like React-Native.
""".trimMargin(">")
println(str3)
複製程式碼

輸出結果為:

 I`m like Kotlin .
 I`m like Java .
 I`m like Android .
 I`m like React-Native.
複製程式碼

3、字串模板

使用字串模板的符號為($)。在$符號後面加上變數名或大括號中的表示式

例:

val text1: String = "我來了!"
var text2: String = "$text1 kotlin"
var text3: String = "$text2 ${text1.length} 哈哈!!!!"
println(text1)
println(text2)
println(text3)
複製程式碼

輸出結果為:

我來了!
我來了! kotlin
我來了! kotlin 4 哈哈!!!!
複製程式碼

五、陣列型(Array)

  • Kotlin中陣列由Array<T>表示,可以去看看原始碼實現,裡面就幾個方法
  • 建立陣列的3個函式
    1. arrayOf()
    2. arrayOfNulls()
    3. 工廠函式(Array()

1、arrayOf()

建立一個陣列,引數是一個可變引數的泛型物件

例:

var arr1 = arrayOf(1,2,3,4,5) //等價於[1,2,3,4,5]
for (v in arr1){
    print(v)
    print("	")
}

var arr2 = arrayOf("0","2","3",`a`,32.3f)
for (v in arr2){
    print(v)
    print("	")
}
複製程式碼

輸出結果為:

1	2	3	4	5	
0	2	3	a	32.3	
複製程式碼

2、arrayOfNulls()

用於建立一個指定資料型別且可以為空元素的給定元素個數的陣列

例:

var arr3 = arrayOfNulls<Int>(3)

//如若不予陣列賦值則arr3[0]、arr3[1]、arr3[2]皆為null
for(v in arr3){
    print(v)
    print("	")
}

println()

//為陣列arr3賦值
arr3[0] = 10
arr3[1] = 20
arr3[2] = 30

for(v in arr3){
    print(v)
    print("	")
}
複製程式碼

輸出結果為:

null	null	null	
10	20	30	
複製程式碼

3、工廠函式

  • 使用一個工廠函式Array(),它使用陣列大小和返回給定其索引的每個陣列元素的初始值的函式。
  • Array() => 第一個參數列示陣列元素的個數,第二個引數則為使用其元素下標組成的表示式

例:

var arr4 = Array(5,{index -> (index * 2).toString() })
for (v in arr4){
    print(v)
    print("	")
}
複製程式碼

輸出結果為:

0	2	4	6	8
複製程式碼

4、原始型別陣列

  • Kotlin還有專門的類來表示原始型別的陣列,沒有裝箱開銷,它們分別是:

    1. ByteArray => 表示位元組型陣列
    2. ShortArray => 表示短整型陣列
    3. IntArray => 表示整型陣列
    4. LongArray => 表示長整型陣列
    5. BooleanArray => 表示布林型陣列
    6. CharArray => 表示字元型陣列
    7. FloatArray => 表示浮點型陣列
    8. DoubleArray => 表示雙精度浮點型陣列
  • PS: Kotlin中不支援字串型別這種原始型別陣列,可以看原始碼Arrays.kt這個類中並沒有字串陣列的宣告。而原始碼中StringArray.kt這個類並不是宣告字串型陣列的。

下面的例子只演示了幾種,其他的類似。
例:

var intArr: IntArray = intArrayOf(1,2,3,4,5)
for (number in intArr){
    print(number)
    print("	")
}

println()

var charArr: CharArray = charArrayOf(`a`,`1`,`b`,`c`,`3`,`d`)
for (char in charArr){
    print(char)
    print("	")
}

println()

var longArr: LongArray = longArrayOf(12L,1254L,123L,111L)
for (long in longArr){
    print(long)
    print("	")
}
複製程式碼

輸出結果為:

1	2	3	4	5	
a	1	b	c	3	d	
12	1254   123	111	
複製程式碼

六、尾語

不管對於任何一門程式語言,都有其資料型別,而資料型別是學習一門程式語言的基礎。所以請各位大佬認真並且跟著程式碼敲一遍。特別是陣列字串型別這兩個點。

原始碼

如果各位大佬看了之後感覺還闊以,就請各位大佬隨便star一下,您的關注是我最大的動力。
我的個人部落格Jetictors
GithubJteictors

歡迎各位大佬進群共同研究、探索

QQ群號:497071402
Kotlin——初級篇(三):資料型別詳解

相關文章