函数参数之惑
当一个函数拥有多个参数,且存在多个相同类型参数紧挨着的情况时,往往不太清楚传入参数的位置是否正确,且严重影响函数的可读性。需要调用者跳转到函数对应的地方,对参数和函数定义中的参数列表进行匹对。这将对函数调用者造成很大的麻烦和困扰。
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早已对此进行了优化,在对函数填写参数时,会将参数对应位置的参数名称进行提示。
命名参数
Kotlin在语法层上对该情况进行优化,当调用一个Kotlin定义的函数时,可以显式标明参数的名称。这种参数叫命名参数。
当指明一个参数的名称后,避免混淆,其他参数都要标明名称。(既然显示的标明名称,也就不需要按原本参数定义的顺序传入参数)
joinToString(array,prefix = "(",separator = ",", postfix = "]")
注意:
-
既然显示的标明了参数名,也就意味着当参数名或方法名进行改变时,其标明的参数名或方法名也需要进行改变。这时可以使用Idea的Rename进行修改。(先选中方法名或参数名 -> Refactor -> Rename)
image
- 当调用Java定义的函数时,不能采用命名参数,因为Java8之前不能把参数名存在,class文件中。而Kotlin需要与Java6兼容。所以,编译器不能识别出函数参数的名称。
函数重载之祸
在Java中,支持对函数进行重载。这就造成多个相同名称的函数,且其参数间只有细微的差别。当调用省略部分参数的函数时,可能不清楚到底调用的是哪一个函数。(例如:Thread类拥有8个构造函数)
默认参数
而Kotlin只需要指定参数的默认值,就可以有效避免创建多个重载函数。这种带有默认值的函数参数叫做默认参数。再配合命名参数进行使用时,可以很方便的对指定参数进行赋值,从而实现重载。
fun <T> joinToString(collection: Collection<T>,
separator:String = ",",
prefix:String = "",
postfix:String = ""):String
调用时只需要传入具体的集合对象,函数会使用默认参数的默认值对其进行运算。
当然,按参数定义的顺序,传入对应的参数也完全没有问题。
val string = joinToString(array)
//像以前传递前缀,分割符和后缀也没有问题
val string = joinToString(array,"(",",")
val string = joinToString(array,"(",",", "]")
//配合命名参数食用,效果更佳
val string = joinToString(array,separator = ";")
@JvmOverloads 提高Kotlin与Java的交互性
Java 中没有默认参数的概念,当从Java中调用Kotlin的函数时,必须显示地传递所有参数值。为了让Java调用者能调用该方法的重载函数,可以用@JvmOverloads注解它。在编译时,编译器会从最后一个参数开始逐个省略,生成Java的重载函数。
参考文献:
- 《Kotlin实战》
- Kotlin官网
网友评论