當一個函數擁有多個參數,且存在多個相同類型參數緊挨着的狀況時,每每不太清楚傳入參數的位置是否正確,且嚴重影響函數的可讀性。須要調用者跳轉到函數對應的地方,對參數和函數定義中的參數列表進行匹對。這將對函數調用者形成很大的麻煩和困擾。android
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()
}
複製代碼
針對這種狀況,或許能夠依靠IDE進行優化。如:Idea早已對此進行了優化,在對函數填寫參數時,會將參數對應位置的參數名稱進行提示。bash
Kotlin在語法層上對該狀況進行優化,當調用一個Kotlin定義的函數時,能夠顯示標明參數的名稱。這種參數叫命名參數。app
當指明一個參數的名稱後,避免混淆,其餘參數都要標明名稱。(既然顯式的標明名稱,也就不須要按本來參數定義的順序傳入參數)函數
joinToString(array,prefix = "(",separator = ",", postfix = "]")
複製代碼
在Java中,支持對函數進行重載。這就形成多個相同名稱的函數,且其參數間只有細微的差異。當調用省略部分參數的函數時,可能不清楚到底調用的是哪個函數。(例如:Thread類擁有8個構造函數)post
而Kotlin只須要指定參數的默認值,就能夠有效避免建立多個重載函數。這種帶有默認值的函數參數叫作默認參數。再配合命名參數進行使用時,能夠很方便的對指定參數進行賦值,從而實現重載。優化
fun <T> joinToString(collection: Collection<T>,
separator:String = ",",
prefix:String = "",
postfix:String = ""):String
複製代碼
調用時只須要傳入具體的集合對象,函數會使用默認參數的默認值對其進行運算。ui
固然,按參數定義的順序,傳入對應的參數也徹底沒有問題。spa
val string = joinToString(array)
//像之前傳遞前綴,分割符和後綴也沒有問題
val string = joinToString(array,"(",",")
val string = joinToString(array,"(",",", "]")
//配合命名參數食用,效果更佳
val string = joinToString(array,separator = ";")
複製代碼
Java 中沒有默認參數的概念,當從Java中調用Kotlin的函數時,必須顯示地傳遞全部參數值。爲了讓Java調用者能調用該方法的重載函數,能夠用@JvmOverloads註解它。在編譯時,編譯器會從最後一個參數開始逐個省略,生成Java的重載函數。.net
程序猿都認爲方法越小越好,相比縱向冗長的代碼片斷,將其按照職責切分紅功能單一的小的局部方法,最後組織起來調用是最好的。但不少時候分解出來的小方法之間並無什麼明確的關係,最後以一個包含許多小方法的類了結。3d
Kotlin中支持局部函數,所謂局部函數就是在方法中聲明方法,內部方法能夠獲取到外部函數的參數和局部變量。能夠將各個小方法定義爲局部方法,即提供所需的簡潔結構也無須額外的語法開銷。
data class Person(val age:String?,val name:String?)
fun daqi(person: Person){
if (person.age == null){
throw IllegalArgumentException()
}
if (person.name == null){
throw IllegalArgumentException()
}
//正常操做
}
複製代碼
轉換爲局部函數:
fun daqi(person: Person){
//須要在頂層定義,否則函數未定義沒法使用
fun personFileIsEmpty(value:String?,fileName:String){
if (value == null){
throw IllegalArgumentException("$fileName is null")
}
}
personFileIsEmpty(person.age,"age")
personFileIsEmpty(person.name,"name")
//正常操做
}
複製代碼
局部函數的缺點是:局部函數的不能聲明爲內聯,而且擁有局部函數的的函數也不能聲明爲內聯。暫時沒有任何辦法避免這種函數的調用成本。