函數(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在語法層上對(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ù)也完全沒有問題电谣。
val string = joinToString(array)
//像以前傳遞前綴秽梅,分割符和后綴也沒有問題
val string = joinToString(array,"(",",")
val string = joinToString(array,"(",",", "]")
//配合命名參數(shù)食用抹蚀,效果更佳
val string = joinToString(array,separator = ";")
@JvmOverloads 提高Kotlin與Java的交互性
????????Java 中沒有默認(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ǔ)語法
Kotlin知識(shí)歸納(二) —— 讓函數(shù)更好調(diào)用
Kotlin知識(shí)歸納(三) —— 頂層成員與擴(kuò)展
Kotlin知識(shí)歸納(六) —— 類型系統(tǒng)