Kotlin 系列(二) 基本語(yǔ)法(1)

image

屬性與變量

Kotlin 類(lèi)中的屬性,既可以使用關(guān)鍵字 var 聲明為可變的,也可以用 val 聲明為只能賦值一次的只讀變量。

變量

/**
*只讀變量
*/
val a: Int = 1 //立即賦值

val b = 30 //自動(dòng)推斷出 Int 類(lèi)型

val c = "hello" //自動(dòng)推斷出 String 類(lèi)型
/**
*可變變量
*/
var name: String = "keven" //立即賦值

var age: Int = 18 //立即賦值

var address: String = "北京" //立即賦值

類(lèi)

Kotlin 中使用關(guān)鍵字 class 聲明類(lèi)

class Person { 
    
}
構(gòu)造函數(shù)

在 Kotlin 中的一個(gè)類(lèi)可以有一個(gè)主構(gòu)造函數(shù)以及一個(gè)或多個(gè)次構(gòu)造函數(shù)。主構(gòu)造函數(shù)是類(lèi)頭的一部分:它跟在類(lèi)名(與可選的類(lèi)型參數(shù))后。

class Person constructor(firstName: String) {
    
}

如果主構(gòu)造函數(shù)沒(méi)有任何注解或者可見(jiàn)性修飾符,可以省略這個(gè) constructor 關(guān)鍵字。

class Person(firstName: String) { 
}

也可以在類(lèi)中定義次構(gòu)造函數(shù)

class Person {

    //定義一些可變變量
    var name: String = "keven"
    var age: Int = 18
    var address: String = "北京"

    //定義帶參數(shù)構(gòu)造函數(shù)
    constructor(name: String, age: Int, address: String) {
        this.name = name
        this.age = age
        this.address = address
    }
    
    //無(wú)參構(gòu)造函數(shù)
    constructor()

}

使用 Person 類(lèi)

//Kotlin 中沒(méi)有 new 關(guān)鍵字
var result = Person()  //使用無(wú)參構(gòu)造函數(shù)
result.name = "KEVEN"  //給變量賦值
result.age = 19
result.address = "上海"

//使用有參構(gòu)造函數(shù)
var person=Person("Keven",20,"深圳")

函數(shù)

Kotlin 中的函數(shù)使用 fun 關(guān)鍵字聲明

1. 定義帶參函數(shù)

注意:如果一個(gè)函數(shù)不返回任何有用的值,它的返回類(lèi)型是 Unit。Unit 是一種只有一個(gè)值 Unit 的類(lèi)型。這個(gè)值不需要顯式返回

//帶有兩個(gè) Int 參數(shù)
//$a $b $c 代表引用 a、b、c 的值
fun printSum(a: Int, b: Int) {
    var c=a+b
    println("sum of $a and $b is $c")
}

2. 定義帶參數(shù)、帶返回值的函數(shù)

//帶有兩個(gè) Int 類(lèi)型參數(shù),返回值為 Int 類(lèi)型
fun Sum(a: Int, b: Int): Int {
    return a + b
}

3.單表達(dá)式函數(shù)

將表達(dá)式作為函數(shù)體,返回值類(lèi)型自動(dòng)推斷的函數(shù)

fun sum(a: Int, b: Int) = a + b

4. 定義參數(shù)有默認(rèn)值的函數(shù)

//其中 Boolean 類(lèi)型參數(shù) isMale 默認(rèn)值為 true
//其中 Char 類(lèi)型參數(shù) short 默認(rèn)值為 'a'
fun reformat(name: String, isMale: Boolean = true, short: Char = 'a') {

    }
    
//調(diào)用有默認(rèn)值參數(shù)的函數(shù)時(shí),可不傳有默認(rèn)值的參數(shù)
reformat("CUE")
//當(dāng)然也可以全傳遞
reformat("CUE",true,'C')

5. 可變數(shù)量參數(shù)的函數(shù)

函數(shù)的參數(shù)(通常是最后一個(gè))可以用 vararg 修飾符標(biāo)記

//使用 vararg 進(jìn)行參數(shù)修飾
fun asList(vararg list: Int) {
    for (a in list)
        println("a = $a")
}

對(duì)于可變參數(shù)函數(shù)進(jìn)行調(diào)用

//傳入任意個(gè)數(shù) Int 類(lèi)型參數(shù)
asList(1, 2, 3, 4)

asList(0, 1, 2)

字符串模板

字符串可以包含模板表達(dá)式 ,即一些小段代碼,會(huì)求值并把結(jié)果合并到字符串中。 模板表達(dá)式以美元符($)開(kāi)頭,由一個(gè)簡(jiǎn)單的名字構(gòu)成:

val i = 10
println("i = $i") // 輸出“i = 10”

或者用花括號(hào)括起來(lái)的任意表達(dá)式:

val s = "abc"
println("$s.length is ${s.length}") // 輸出“abc.length is 3”

原始字符串與轉(zhuǎn)義字符串內(nèi)部都支持模板。 如果你需要在原始字符串中表示字面值 $ 字符(它不支持反斜杠轉(zhuǎn)義),你可以用下列語(yǔ)法:

val price = """${'$'}9.99"""
println(price)//輸出“$9.99”

if 表達(dá)式

在 Kotlin 中,if 是一個(gè)表達(dá)式,即它會(huì)返回一個(gè)值。 因此就不需要三元運(yùn)算符(條件 ? 然后 : 否則),因?yàn)槠胀ǖ?if 就能勝任這個(gè)角色。

// 傳統(tǒng)用法
var max = a 
if (a < b) max = b

// With else 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
 
// 作為表達(dá)式
val max = if (a > b) a else b

if 的分支可以是代碼塊,最后的表達(dá)式作為該塊的值

//輸出 a、b 中較大的一項(xiàng)
var a = 1
var b = 2
val max = if (a > b) {
    a
} else {
    b
}

使用可空值及 null 檢測(cè)

許多編程語(yǔ)言(包括 Java)中最常見(jiàn)的陷阱之一,就是訪問(wèn)空引用的成員會(huì)導(dǎo)致空引用異常。在 Java 中,這等同于 NullPointerException 或簡(jiǎn)稱(chēng) NPE。

Kotlin 的類(lèi)型系統(tǒng)旨在從我們的代碼中消除 NullPointerException。

使用

在 Kotlin 中,類(lèi)型系統(tǒng)區(qū)分一個(gè)引用可以容納 null (可空引用)還是不能容納(非空引用)。 例如,String 類(lèi)型的常規(guī)變量不能容納 null:

var a: String = "abc"
a = null // 編譯錯(cuò)誤

如果要允許為空,我們可以聲明一個(gè)變量為可空字符串,寫(xiě)作 String?:

var b: String? = "abc"
b = null // ok
print(b)

檢測(cè)

val b: String? = "Kotlin"
if (b != null && b.length > 0) {
    print("String of length ${b.length}")
} else {
    print("Empty string")
}

這只適用于 b 是不可變的情況(即在檢查和使用之間沒(méi)有修改過(guò)的局部變量 ,或者不可覆蓋并且有幕后字段的 val 成員),因?yàn)榉駝t可能會(huì)發(fā)生在檢查之后 b 又變?yōu)?null 的情況。

安全的調(diào)用

安全調(diào)用操作符,寫(xiě)作 ?.:

val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length) // 無(wú)需安全調(diào)用

如果 b 非空,就返回 b.length,否則返回 null,這個(gè)表達(dá)式的類(lèi)型是 Int?。

安全調(diào)用在鏈?zhǔn)秸{(diào)用中很有用。例如,如果一個(gè)員工 Bob 可能會(huì)(或者不會(huì))分配給一個(gè)部門(mén), 并且可能有另外一個(gè)員工是該部門(mén)的負(fù)責(zé)人,那么獲取 Bob 所在部門(mén)負(fù)責(zé)人(如果有的話(huà))的名字,我們寫(xiě)作:

bob?.department?.head?.name

如果任意一個(gè)屬性(環(huán)節(jié))為空,這個(gè)鏈?zhǔn)秸{(diào)用就會(huì)返回 null。

如果要只對(duì)非空值執(zhí)行某個(gè)操作,安全調(diào)用操作符可以與 let 一起使用:

val listWithNulls: List<String?> = listOf("Kotlin", null)
for (item in listWithNulls) {
    item?.let { println(it) } // 輸出 Kotlin 并忽略 null
}

安全調(diào)用也可以出現(xiàn)在賦值的左側(cè)。這樣,如果調(diào)用鏈中的任何一個(gè)接收者為空都會(huì)跳過(guò)賦值,而右側(cè)的表達(dá)式根本不會(huì)求值:

// 如果 `person` 或者 `person.department` 其中之一為空,都不會(huì)調(diào)用該函數(shù):
person?.department?.head = managersPool.getManager()

Elvis 操作符

判斷如果 b 不為 null ,返回 b 的長(zhǎng)度,否則返回 -1

val l: Int = if (b != null) b.length else -1

除了完整的 if-表達(dá)式,這還可以通過(guò) Elvis 操作符表達(dá),寫(xiě)作 ?:

val l = b?.length ?: -1

如果 ?: 左側(cè)表達(dá)式非空,elvis 操作符就返回其左側(cè)表達(dá)式,否則返回右側(cè)表達(dá)式。 請(qǐng)注意,當(dāng)且僅當(dāng)左側(cè)為空時(shí),才會(huì)對(duì)右側(cè)表達(dá)式求值。

請(qǐng)注意,因?yàn)?throw 和 return 在 Kotlin 中都是表達(dá)式,所以它們也可以用在 elvis 操作符右側(cè)。這可能會(huì)非常方便,例如,檢查函數(shù)參數(shù):

fun foo(node: Node): String? {
    val parent = node.getParent() ?: return null
    val name = node.getName() ?: throw IllegalArgumentException("name expected")
    // ……
}

安全的類(lèi)型轉(zhuǎn)換

如果對(duì)象不是目標(biāo)類(lèi)型,那么常規(guī)類(lèi)型轉(zhuǎn)換可能會(huì)導(dǎo)致 ClassCastException。 另一個(gè)選擇是使用安全的類(lèi)型轉(zhuǎn)換,如果嘗試轉(zhuǎn)換不成功則返回 null

val aInt: Int? = a as? Int

可空類(lèi)型的集合

如果你有一個(gè)可空類(lèi)型元素的集合,并且想要過(guò)濾非空元素,你可以使用 filterNotNull 來(lái)實(shí)現(xiàn)

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()

本小節(jié)就介紹到這里,下一小節(jié)我們會(huì)繼續(xù)學(xué)習(xí) Kotlin 的基本語(yǔ)法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容