# 函数

## 函数

### 函数声明

``````fun double(x: Int): Int {

}``````

### 函数用法

``val result = double(2) ``

``Sample().foo() // 创建Sample类的实例,调用foo方法``

### 中缀符号

它们是成员函数或者是扩展函数
只有一个参数

``````//给 Int 定义一个扩展方法
infix fun Int.shl(x: Int): Int {
...
}

1 shl 2 //用中缀注解调用扩展函数

1.shl(2)``````

### 参数

``````fun powerOf(number: Int, exponent: Int) {
...
}``````

### 默认参数

``````fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size ) {
...
}``````

### 命名参数

``````fun reformat(str: String, normalizeCase: Boolean = true,upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' ') {
...
}``````

reformat(str)

``reformat(str, true, true, false, '_')``

``````reformat(str,
normalizeCase = true,
uppercaseFirstLetter = true,
divideByCamelHumps = false,
wordSeparator = '_'
)``````

``reformat(str, wordSeparator = '_')``

### 不带返回值的参数

``````fun printHello(name: String?): Unit {
if (name != null)
println("Hello \${name}")
else
println("Hi there!")
// `return Unit` or `return` is optional
}``````

`Unit` 返回值也可以省略，比如下面这样：

``````fun printHello(name: String?) {
...
}``````

### 单表达式函数

``fun double(x: Int): Int = x*2``

``````fun double(x: Int) = x * 2
``````

### 变长参数

``````fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts)
return result
}``````

``val list = asList(1, 2, 3)``

``````val a = array(1, 2, 3)
val list = asList(-1, 0, *a, 4)``````

### 函数范围

Kotlin 中可以在文件顶级声明函数，这就意味者你不用像在Java,C#或是Scala一样创建一个类来持有函数。除了顶级函数，Kotlin 函数可以声明为局部的，作为成员函数或扩展函数。

#### 局部函数

Kotlin 支持局部函数，比如在一个函数包含另一函数。

``````fun dfs(graph: Graph) {
fun dfs(current: Vertex, visited: Set<Vertex>) {
for (v in current.neighbors)
dfs(v, visited)
}

dfs(graph.vertices[0], HashSet())
}``````

``````fun dfs(graph: Graph) {
val visited = HashSet<Vertex>()
fun dfs(current: Vertex) {
for (v in current.neighbors)
dfs(v)
}
dfs(graph.vertices[0])
}``````

``````fun reachable(from: Vertex, to: Vertex): Boolean {
val visited = HashSet<Vertex>()
fun dfs(current: Vertex) {
if (current == to) return@reachable true
for (v  in current.neighbors)
dfs(v)
}
dfs(from)
return false
}``````

### 成员函数

``````class Sample() {
fun foo() { print("Foo") }
}``````

``Sample.foo()``

### 泛型函数

``````fun <T> sigletonArray(item: T): Array<T> {
return Array<T>(1, {item})
}``````

### 尾递归函数

Kotlin 支持函数式编程的尾递归。这个允许一些算法可以通过循环而不是递归解决问题，从而避免了栈溢出。当函数被标记为 `tailrec` 时，编译器会优化递归，并用高效迅速的循环代替它。

``````tailrec fun findFixPoint(x: Double = 1.0): Double
= if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))``````

``````private fun findFixPoint(): Double {
var x = 1.0
while (true) {
val y = Math.cos(x)
if ( x == y ) return y
x = y
}
}``````