Kotlin知識(shí)歸納(二) —— 讓函數(shù)更好調(diào)用

函數(shù)參數(shù)之惑

????????當(dāng)一個(gè)函數(shù)擁有多個(gè)參數(shù),且存在多個(gè)相同類型參數(shù)緊挨著的情況時(shí),往往不太清楚傳入?yún)?shù)的位置是否正確,且嚴(yán)重影響函數(shù)的可讀性。需要調(diào)用者跳轉(zhuǎn)到函數(shù)對(duì)應(yīng)的地方,對(duì)參數(shù)和函數(shù)定義中的參數(shù)列表進(jìn)行匹對(duì)。這將對(duì)函數(shù)調(diào)用者造成很大的麻煩和困擾。

fun <T> joinToString(collection: Collection<T>,
                     separator:String,
                     prefix:String,
                     postfix:String):String{
    val result = StringBuilder(prefix)
    for ((index,element) in collection.withIndex()){
        if (index > 0)
            result.append(separator)
        result.append(element)
    }
    result.append(postfix)
    return result.toString()
}

????????針對(duì)這種情況,或許可以依靠IDE進(jìn)行優(yōu)化。如:Idea早已對(duì)此進(jìn)行了優(yōu)化,在對(duì)函數(shù)填寫參數(shù)時(shí),會(huì)將參數(shù)對(duì)應(yīng)位置的參數(shù)名稱進(jìn)行提示。

image

命名參數(shù)

????????Kotlin在語(yǔ)法層上對(duì)該情況進(jìn)行優(yōu)化,當(dāng)調(diào)用一個(gè)Kotlin定義的函數(shù)時(shí),可以顯式標(biāo)明參數(shù)的名稱。這種參數(shù)叫命名參數(shù)。

當(dāng)指明一個(gè)參數(shù)的名稱后,避免混淆,其他參數(shù)都要標(biāo)明名稱。(既然顯示的標(biāo)明名稱,也就不需要按原本參數(shù)定義的順序傳入?yún)?shù))

joinToString(array,prefix = "(",separator = ",", postfix = "]")

注意:

  • 既然顯示的標(biāo)明了參數(shù)名,也就意味著當(dāng)參數(shù)名或方法名進(jìn)行改變時(shí),其標(biāo)明的參數(shù)名或方法名也需要進(jìn)行改變。這時(shí)可以使用Idea的Rename進(jìn)行修改。(先選中方法名或參數(shù)名 -> Refactor -> Rename)


    image
  • 當(dāng)調(diào)用Java定義的函數(shù)時(shí),不能采用命名參數(shù),因?yàn)镴ava8之前不能把參數(shù)名存在,class文件中。而Kotlin需要與Java6兼容。所以,編譯器不能識(shí)別出函數(shù)參數(shù)的名稱。

函數(shù)重載之禍

????????在Java中,支持對(duì)函數(shù)進(jìn)行重載。這就造成多個(gè)相同名稱的函數(shù),且其參數(shù)間只有細(xì)微的差別。當(dāng)調(diào)用省略部分參數(shù)的函數(shù)時(shí),可能不清楚到底調(diào)用的是哪一個(gè)函數(shù)。(例如:Thread類擁有8個(gè)構(gòu)造函數(shù))

默認(rèn)參數(shù)

????????而Kotlin只需要指定參數(shù)的默認(rèn)值,就可以有效避免創(chuàng)建多個(gè)重載函數(shù)。這種帶有默認(rèn)值的函數(shù)參數(shù)叫做默認(rèn)參數(shù)。再配合命名參數(shù)進(jìn)行使用時(shí),可以很方便的對(duì)指定參數(shù)進(jìn)行賦值,從而實(shí)現(xiàn)重載。

fun <T> joinToString(collection: Collection<T>,
                          separator:String = ",",
                          prefix:String = "",
                          postfix:String = ""):String

調(diào)用時(shí)只需要傳入具體的集合對(duì)象,函數(shù)會(huì)使用默認(rèn)參數(shù)的默認(rèn)值對(duì)其進(jìn)行運(yùn)算。

當(dāng)然,按參數(shù)定義的順序,傳入對(duì)應(yīng)的參數(shù)也完全沒(méi)有問(wèn)題。

val string = joinToString(array)
//像以前傳遞前綴,分割符和后綴也沒(méi)有問(wèn)題
val string = joinToString(array,"(",",")
val string = joinToString(array,"(",",", "]")
//配合命名參數(shù)食用,效果更佳
val string = joinToString(array,separator = ";")

@JvmOverloads 提高Kotlin與Java的交互性

????????Java 中沒(méi)有默認(rèn)參數(shù)的概念,當(dāng)從Java中調(diào)用Kotlin的函數(shù)時(shí),必須顯示地傳遞所有參數(shù)值。為了讓Java調(diào)用者能調(diào)用該方法的重載函數(shù),可以用@JvmOverloads注解它。在編譯時(shí),編譯器會(huì)從最后一個(gè)參數(shù)開始逐個(gè)省略,生成Java的重載函數(shù)。

image

參考文獻(xiàn):

android Kotlin系列:

Kotlin知識(shí)歸納(一) —— 基礎(chǔ)語(yǔ)法

Kotlin知識(shí)歸納(二) —— 讓函數(shù)更好調(diào)用

Kotlin知識(shí)歸納(三) —— 頂層成員與擴(kuò)展

Kotlin知識(shí)歸納(四) —— 接口和類

Kotlin知識(shí)歸納(五) —— Lambda

Kotlin知識(shí)歸納(六) —— 類型系統(tǒng)

Kotlin知識(shí)歸納(七) —— 集合

Kotlin知識(shí)歸納(八) —— 序列

Kotlin知識(shí)歸納(九) —— 約定

Kotlin知識(shí)歸納(十) —— 委托

Kotlin知識(shí)歸納(十一) —— 高階函數(shù)

Kotlin知識(shí)歸納(十二) —— 泛型

Kotlin知識(shí)歸納(十三) —— 注解

Kotlin知識(shí)歸納(十四) —— 反射

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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