当一个函数拥有多个参数,且存在多个相同类型参数紧挨着的状况时,每每不太清楚传入参数的位置是否正确,且严重影响函数的可读性。须要调用者跳转到函数对应的地方,对参数和函数定义中的参数列表进行匹对。这将对函数调用者形成很大的麻烦和困扰。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")
//正常操做
}
复制代码
局部函数的缺点是:局部函数的不能声明为内联,而且拥有局部函数的的函数也不能声明为内联。暂时没有任何办法避免这种函数的调用成本。