函數(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)行提示。
命名參數(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ù)。
參考文獻(xiàn):
- 《Kotlin實(shí)戰(zhàn)》
- Kotlin官網(wǎng)
android Kotlin系列:
Kotlin知識(shí)歸納(一) —— 基礎(chǔ)語(yǔ)法
Kotlin知識(shí)歸納(二) —— 讓函數(shù)更好調(diào)用
Kotlin知識(shí)歸納(三) —— 頂層成員與擴(kuò)展
Kotlin知識(shí)歸納(六) —— 類型系統(tǒng)