函数
参数:Pascal表示法 ---》 name : type
- 多参数用逗号隔开
- 参数赋值: 例如 name:type = 给予的默认值(= value如果没有默认值,这部分是可以省略的)
- 覆盖方法(override)总是使用与基类型方法相同的默认参数值。当覆盖一个带有默认参数值的方法时,必须从签名中省略默认参数值。
具名参数: name = value
在多参数的函数中,如果有些参数添加了默认值,这时在调用时,就可以省略掉,但是调用时必须使用具名参数格式调用,例子如下:
多参函数
fun foo(bar: Int = 0, baz: Int) { /*……*/ }
省略默认值参数,使用具名参数调用
foo(baz = 1) // 使用默认值 bar = 0
函数如果在默认参数的最后一个参数是Lambda表达式, 那么它可以用具名参数在括号内传入,也可以在括号外传入。
例子:
多默认参数函数
fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { /*……*/ }
foo(1) { println("hello") } // 使用默认值 baz = 1
foo(qux = { println("hello") }) // 使用两个默认值 bar = 0 与 baz = 1
foo { println("hello") } // 使用两个默认值 bar = 0 与 baz = 1
当一个函数调用混用位置参数与具名参数时,所有位置参数都要放在第一个具名参数之前。例如,允许调用f(1,y=2) 但不允许f(x=1,2)。
可以通过使用星号操作符将可变数量参数(vararg)以具名形式传入:
fun foo(vararg string:String){/******/}
调用
foo(string = *arrayOf("a", "b", "c"))
返回Unit函数
在函数中Unit的返回类型是可选的:return Unit 或者 return
可变数量参数
函数中可以用可变数量参数,但是一般都是放在参数的最后一个(如果不是最后一个,那此参数后面参数使用具名参数语法传入),可以用vararg修饰符标记
例子:
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) // ts is an Array
result.add(t)
return result
}
调用:
val list = asList(1,2,3)
如果已经有一个数组并希望将其内容传给该函数,我们使用伸展(spread)操作符(在数组前面加*)
调用例子:
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
函数的作用域
局部函数
kotlin支持局部函数,即一个函数在另一个函数内部。
fun dfs(graph: Graph) {
fun dfs(current: Vertex, visited: MutableSet<Vertex>) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v, visited)
}
dfs(graph.vertices[0], HashSet())
}
局部函数可以访问外部函数(即闭包)的局部变量,所以在上例中,visited可以是局部变量:
fun dfs(graph: Graph) {
val visited = HashSet<Vertex>()
fun dfs(current: Vertex) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v)
}
dfs(graph.vertices[0])
}
成员函数
成员函数是在类或对象内部定义的函数
class Sample() {
fun foo() { print("Foo") }
}
成员函数以点表示法调用
Sample().foo() // 创建类 Sample 实例并调用 foo
泛型函数
函数可以有泛型参数,通过在函数名前使用尖括号指定:
fun <T> singletonList(item: T): List<T> { /*……*/ }