函数可以定义特定功能的代码块。
一、函数定义
Kotlin语言定义函数的基本形式:
fun 函数名(【参数:参数类型,参数:参数类型…】)【:返回值类型】{
//函数体
}
如果函数体只有一条返回值,也可以简化成如下形式:
fun 函数名(【参数:参数类型,参数:参数类型…】)【:返回值类型】=表达式
以上【】表示可选项,可以忽略。
例:定义一个执行加法的函数,可以定义:
fun add(x:Int,y:Int){
return x+y
}
或
fun add(x:Int,y:Int) = x+y
二、特殊函数
1.扩展函数
Kotlin通过扩展函数提供为已有的类的新的功能而无需继承该类或使用装饰者模式这样的设计模式。定义形式如下:
fun 类名.函数名([参数1,参数2,….]):返回类型{
//方法体
}
例,为String类增加一个新的函数display,定义如下:
fun String.display(){
println(this)
}
则调用下列代码块:
"hello".display()
运行结果是:
hello
2.高阶函数
Kotlin中支持函数的参数(也可以表示为Lambda表达式)或者返回值为函数(Lambda表达式),具有这样形式的函数称为高阶函数
2.1 函数作为函数的参数
例:
fun operate(x:Double,y:Double,operator:(Double,Double)->Any):Any = operator(x,y)
在上述代码中定义了函数参数operator,并返回operator运算的结果作为函数的返回值。
调用上述函数:
val method = {x:Double,y:Double->
x+y
}
val result = operate(20.0,30.0,method)
或
val result=operate(20.0,30.0,operator= { x:Double,y:Double->
x+y
})
或
val result = operate(20.0,30.0) { x, y ->
x + y
}
2.2 函数作为函数的返回值
fun operate(expression:String):(Double,Double)->Any {
val op = when{
expression.contains("+")->::add
expression.contains("-")->::sub
expression.contains("x")->::mul
expression.contains("/")->::div
expression.contains("%")->::mod
expression.contains(">")->::isBigger
else->throw ArithmeticException("$expression 出现错误!")
}
return op
}
其中,add,sub,mul,div等均为已经定义的函数。类似如下形式
fun add(x:Double,y:Double) = x+y
fun sub(x:Double,y:Double) = x-y
fun mul(x:Double,y:Double) = x*y
fun div(x:Double,y:Double) = x/y
fun mod(x:Double,y:Double) = x%y
fun isBigger(x:Double,y:Double) = x>y
3.内联函数
内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展)。在Kotlin语言中当一个函数被内联 inline 标注后,在调用它的地方,会把这个函数方法体中的所有代码移动到调用的地方,而不是通过方法间压栈进栈的方式。在编译时期,把调用这个函数的地方用这个函数的方法体进行替换。
inline fun show(message:String){
println(message)
}
fun main(){
println("main测试内联函数")
show("内联函数")
println("测试结束")
}
在Android Studio中选择Tools/Kotlin/Show Kotlin Bytecodes,则显示结果如下所示:
单击Decompile按钮,显示反编译的代码
Inline往往用在Lambda表达式上,可以带来性能上的提升。
inline fun operateArithmetic(op:String):(Double,Double)->Any{
return when(op){
"+"->::add
"-"->::sub
"x"->::mul
"/"->::div
"%"->::mod
">"->::isBigger
else-> throw ArithmeticException("运算错误!")
}
}
fun main(){
println("main测试内联函数")
val op = operateArithmetic("+")
println(op(23.34,45.034))
println("测试结束")
}
三.标准函数
1.let函数
let函数在对象的上下文中执行一个代码块,使得代码执行更加简洁
定义形式:
@InlineOnly
public inline fun <T, R> T.let(block: (T) -> R):R
例:
fun main(){
val message:String? = "hello kotlin world"
//let将当前对象message执行多次操作
val c = message?.let {it:String->
println(it.length)
println(it.lines())
"something"
}
println(message)
println(c)
}
运行结果是:
18
[hello kotlin world]
hello kotlin world
something
在上述代码中,如果删除”something”则let函数调用没有返回值
2.with函数
with函数以给定的接收者作为接收者调用指定的函数块并返回其结果,是处理对某一个对象连续调用多次调用它的相关方法的处理。
定义的基本形式:
@InlineOnly
public inline fun <T, R> with(
receiver: T,
block: T.() -> R
): R
例:
fun main(){
var message="hello kotlin world"
val c=with(message){
println(length)
println(lines())
"$this welcome to new world"
}//返回最后一行的结果
println(message)
println(c)
}
运行结果是:
18
[hello kotlin world]
hello kotlin world
hello kotlin world welcome to new world
3.run函数
run函数使用this作为接受器来访问当前对象,执行对某个对象的多次不同的调用,并返回结果。它接受一个Lambda表达式作为参数。当前对象作为Lambda表达式的上下文。调用run函数,返回值为Lambda函数块最后一行,或者指定return表达式。用this访问函数块
定义的基本形式:
@InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R
例:
fun main(){
var message = "hello kotlin world"
val c =message.run{
println(this.length)
println(this.lines())
"$this welcome to new world"
}//返回最后一行的结果
println(message)
println(c)
}
4.apply函数
apply函数的主要作用是简化初始化对象的功能。apply函数接受一个Lambda表达式,Lambda表达式中的上下文就是这个对象本身。apply函数的返回值是对象本身。
定义的基本形式:
@InlineOnly
public inline fun T.apply(block: T.() -> Unit): T
例:
fun main(){
var message:String? = "hello kotlin world"
val c = message?.apply{
println(length)
lines()+" welcome "
}//返回this对象
println(c)
println(message)
}
运行结果是:*
18
hello kotlin world
hello kotlin world*
5.also函数
also函数适用于let函数的任何场景,一般可用于多个扩展函数链式调用。also函数与let函数有些相似又有自己的特点:一方面also函数将当前对象作为Lambda表达式的上下文;另外一方面,also函数的返回值是就是传入的当前对象。
定义的基本形式:
@InlineOnly
@SinceKotlin
public inline fun T.also(block: (T) -> Unit): T
例:
fun main(){
var message:String? = "hello kotlin world"
val c = message?.also{
println(it.length)
it.lines()+" welcome "
}//返回this对象
println(c)
println(message)
}
运行结果是:
18
hello kotlin world
hello kotlin world
参考文献
陈轶《Android移动应用开发(微课版)》 清华大学出版社 ISBN 978-7-302-59734-6