函数
默认参数
函数参数可以有默认值,当省略相应的参数时使用默认值。与其他语言相比,这可以减少重载数量:
fun test(a: Int = 0, b: Int = 1) = print(a - b)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main16)
test()
test(2)//2传给了a,安装顺序来传
test(b = 2)//显式指定参数名
test(3, 2)//3赋值给a,2赋值给b
test(a = 3)
}
对于重写的方法来说,子类所拥有的重写方法会使用父类相同的默认参数值
在重写一个拥有默认参数值的方法时,方法签名中必须要将默认参数值省略掉
open class A {
open fun method(a: Int, b: Int = 4) = a + b
}
class B :A(){
override fun method(a: Int, b: Int): Int {
return super.method(a, b)
}
}
类B中的b是有默认值4
println(A().method(1))//5
println(B().method(2))//6
如果一个默认参数在一个无默认值的参数之前,那么该默认值只能通过使用具名参数调用该函数来使用:
fun test2(a: Int = 1, b: Int) = print(a - b)
test2(b = 3) // 使用默认值 a = 1
fun test(a: Int = 0, b: Int = 1) = print(a - b)
fun test3(a: Int = 1, b: Int = 2, compute: (x: Int, y: Int) -> Unit) {
compute(a, b)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main16)
test3(2,3,::test) //-1
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main16)
test3(2, 3, { x, y -> println(x - y) })
}
如果在默认参数之后的最后一个参数是 lambda 表达式,那么它既可以作为具名参数在括号内传入,也可以在括号外传入:
test3 (2,3){ x, y -> println(x - y) }
第一个参数 :2
第二个参数 :3
第三个参数:{ x, y -> println(x - y) }
test3 (2){ x, y -> println(x - y) }
test3 (){ x, y -> println(x - y) }
可变参数(vararg)
fun test4(vararg strings: String) {
println(strings.javaClass)
strings.forEach { println(it) }
}
test4("a", "b", "c")
strings是字符串数组类型,这个和Java一样。在Java中可以传一个数组,但是Kotlin是不可以把数组直接传给可变参数。可以通过星号操作符来解决
test5(strings = *arrayOf("a", "b", "c"))
Java和Kotlin可以百分之白互操作的,这里有个注意点:
在调用 Java 函数时不能使用具名参数语法,因为 Java 字节码并不总是保留函数参数的名称。
Kotlin中只允许一个参数是可变参数,通常是最后一个参数,如果不是最后一个参数,那么其后的参数就需要用具名参数的形式进行传递,如果其后的参数是函数类型,还可以通过圆括号外传递Lambda传递表达式来实现。
fun <T> convertToList(vararg elements: T): List<T> {
val result = ArrayList<T>()
elements.forEach { result.add(it) }
return result
}
println(convertToList("hello", "world", "Hello World"))
val list = arrayOf("one", "two", "tree")
println(convertToList("hello", "world", *list))
中缀表示法
标有 infix 关键字的函数也可以使用中缀表示法(忽略该调用的点与圆括号)调用。中缀函数必须满足以下要求:
class InfixTest(private var a: Int) {
infix fun add(b: Int) = this.a + b
}
val infixTest = InfixTest(4)
println(infixTest.add(6))
println("---------")
println(infixTest add 6)