如果一个函数有代码块体(大括号 {} 内的指令), 而且不返回有意义的值, 编译器会假设其返回值类型是 Unit. Unit 是一种只有一个值的类型, 这个值也叫做 Unit.
除了函数类型参数之外, 你不必指定 Unit 作为返回值类型. 你永远不必显式地 return Unit.
例如, 你可以声明一个 printHello() 函数, 不必返回 Unit:
// 函数类型参数('action')的声明仍然需要明确的返回值类型
fun printHello(name: String?, action: () -> Unit) {
if (name != null)
println("Hello $name")
else
println("Hi there!")
action()
}
fun main() {
printHello("Kodee") {
println("This runs after the greeting.")
}
// 输出结果为:
// Hello Kodee
// This runs after the greeting.
printHello(null) {
println("No name provided, but action still runs.")
}
// 输出结果为: No name provided, but action still runs
}
这段代码与下面这段冗长的声明是等价的:
//sampleStart
fun printHello(name: String?, action: () -> Unit): Unit {
if (name != null)
println("Hello $name")
else
println("Hi there!")
action()
return Unit
}
//sampleEnd
fun main() {
printHello("Kodee") {
println("This runs after the greeting.")
}
// 输出结果为:
// Hello Kodee
// This runs after the greeting.
printHello(null) {
println("No name provided, but action still runs.")
}
// 输出结果为: No name provided, but action still runs
}
如果函数的返回值类型已明确指定, 你可以在表达式体中使用 return 语句:
fun getDisplayNameOrDefault(userId: String?): String =
getDisplayName(userId ?: return "default")
不定数量参数(varargs)
要向函数传递不定数量的参数, 你可以对其中一个参数(通常是最后一个)标记 vararg 修饰符. 在函数内部, 你可以将类型为 T 的 vararg 参数用作 T 类型的数组:
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) // ts 是一个 Array
result.add(t)
return result
}
然后你就可以向函数传递不定数量的参数:
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) // ts 是一个 Array
result.add(t)
return result
}
fun main() {
//sampleStart
val list = asList(1, 2, 3)
println(list)
// 输出结果为: [1, 2, 3]
//sampleEnd
}
class Person(val name: String) {
val friends = mutableListOf<Person>()
}
class SocialGraph(val people: List<Person>)
//sampleStart
fun dfs(graph: SocialGraph) {
fun dfs(current: Person, visited: MutableSet<Person>) {
if (!visited.add(current)) return
println("Visited ${current.name}")
for (friend in current.friends)
dfs(friend, visited)
}
dfs(graph.people[0], HashSet())
}
//sampleEnd
fun main() {
val alice = Person("Alice")
val bob = Person("Bob")
val charlie = Person("Charlie")
alice.friends += bob
bob.friends += charlie
charlie.friends += alice
val network = SocialGraph(listOf(alice, bob, charlie))
dfs(network)
}
class Person(val name: String) {
val friends = mutableListOf<Person>()
}
class SocialGraph(val people: List<Person>)
//sampleStart
fun dfs(graph: SocialGraph) {
val visited = HashSet<Person>()
fun dfs(current: Person) {
if (!visited.add(current)) return
println("Visited ${current.name}")
for (friend in current.friends)
dfs(friend)
}
dfs(graph.people[0])
}
//sampleEnd
fun main() {
val alice = Person("Alice")
val bob = Person("Bob")
val charlie = Person("Charlie")
alice.friends += bob
bob.friends += charlie
charlie.friends += alice
val network = SocialGraph(listOf(alice, bob, charlie))
dfs(network)
}
import kotlin.math.cos
import kotlin.math.abs
// 任意设定的"足够好"的精度
val eps = 1E-10
private fun findFixPoint(): Double {
var x = 1.0
while (true) {
val y = cos(x)
if (abs(x - y) < eps) return x
x = cos(x)
}
}