格式
代码语言:txt复制fun 函数名(参数:参数类型):返回值类型{
函数体
}
笔记
- 如果没有返回值,使用 :Unit 标识,也可以省略不写
- 返回值也是使用 return 返回,Unit 返回值可以忽略 return 语句
- Kotlin 函数参数支持默认值,
fun say(num: Int = 0): Unit
- 支持具名参数调用,
read(text = "内容", start = 0, end = 10)
扩展
代码语言:txt复制变参函数
/**
* 在Kotlin中,使用关键字 vararg 来表示可变参数
*/
fun hasEmpty(vararg strArray: String?): Boolean {
return true
}
代码语言:txt复制中缀调用
/*
中缀调用必须满足下面三个条件:
1.该函数必须为成员函数或者扩展函数
2.必须只有一个参数
3.使用infix关键字修饰
*/
infix fun Int.shl(x: Int): Int {
......
}
// 1 shl 2 <===> 1.shl(2)
代码语言:txt复制函数简化
// 原函数
fun sum(a:Int , b:Int):Int{
return a b
}
// 简化后
fun sum(a:Int , b:Int):Int = a b
代码语言:txt复制扩展函数
// 给父类添加一个方法,这个方法可以在所有子类中使用
// 这样可以在每一个 `Activity` 中直接使用 toast() 函数了
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, duration).show()
}
代码语言:txt复制函数表达式
// 声明函数i,接收两个Int类型参数 x、y,返回 x y 的值(返回一个Int)
var i = {x:Int , y:Int -> x y}
// 调用函数
i(3, 5)
代码语言:txt复制// 声明函数j,它接收的参数是两个Int, 返回一个Int,对应的表达式是 {x,y->x y}
var j:(Int,Int)->Int = {x,y -> x y}
// 调用函数
j(4, 4)
代码语言:txt复制// 下面函数返回的类型都是是:() -> Int
var j: (Int, Int) -> () -> Int = { x, y -> { -> val xx = 23; x y xx; } }
// 没有参数可以去掉 `->`
var j: (Int, Int) -> () -> Int = { x, y -> { val xx = 23; x y xx; } }
var i = { x: Int, y: Int -> { -> val xx = 23; x y xx; } }
// 没有参数可以去掉 `->`
var i = { x: Int, y: Int -> { val xx = 23; x y xx; } }
代码语言:txt复制函数参数
// 可以将一个函数作为参数传递给另一个函数
fun getBody<T>(msg: String, body: () -> T ) : T {
System.out.println(msg)
return body()
}
注意
扩展函数是静态解析的,下面有一个来自网上的例子(https://kymjs.com/code/2017/02/26/01/)
代码语言:txt复制open class Animal{
}
class Dog : Animal()
object Main {
fun Animal.bark() = "animal"
fun Dog.bark() = "dog"
fun Animal.printBark(anim: Animal){
println(anim.bark())
}
@JvmStatic fun main(args: Array<String>) {
Animal().printBark(Dog())
}
}
最终的输出是 animal
,而不是dog
,因为扩展方法是静态解析的,在添加扩展方法的时候类型为Animal
,那么即便运行时传入了子类对象,也依旧会执行参数中声明时类型的方法。