Kotlin中函数 3种表达形式:
1,一般函数:
fun sum(a: Int, b: Int): Int {
return a+b
}
2,简化函数为表达式形式:
fun sum2(a: Int, b: Int): Int = a + b
fun max(a: Int, b: Int): Int = if(a > b) a else b
fun isOdd(x: Int) = x % 2 != 0
调用:sum2(3,2),max(8,9)
带默认参数的函数
//函数参数可以指定默认参数
fun multiply(a:Int,mut:Int=2):Int{
var result = 1
for(i in 0..mut){
result *= a
}
return result
}
3,lambda表达式函数定义:
1. 无参数情况 :
val/var 变量名 = { 操作的代码 }
2. 有参数情况
val/var 变量名 : (参数的类型,参数类型,...) -> 返回值类型 = {参数1,参数2,... -> 操作参数的代码 }
示例:val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
3,自动推导返回值类型(即表达式的返回值类型会根据操作的代码自推导出来)
val/var 变量名 = { 参数1 : 类型,参数2 : 类型, ... -> 操作参数的代码 }
示例:val sumLambda2 = {a : Int , b : Int -> a + b}
例如:
val sumLambda1: (Int, Int) -> Int = {x,y -> x+y}
val sumLambda2 = {a : Int , b : Int -> a + b}
高阶函数:apply/run/also/let/with
kotlin标准库提供了Any对象上下文内执行一段代码块,可用于对象初始化,直接使用对象内部方法,使代码更精简化。
run即可作用于Any,又可作为this代码块,run返回执行的是处理结果
示例:
fun initContentTextView(tvContent:TextView?){
tvContent?.run {//对象初始化处理
this.text = "kotlin"
this.textSize = 13f
this.setCompoundDrawables(null,null,getDrawable(R.drawable.abc_ab_share_pack_mtrl_alpha),null)
}
}
fun getIdentify(index:Int):String{
val person_play = run {//将最后处理结果返回str
when(index){
0 -> "manager"
1 -> "guest"
2 -> "worker"
else -> "none"
}
}
return person_play
}
fun getSampleNickName(nn:String):String{
var sampleName = nn.run {
if(this.length>10)
substring(0,this.length-6)
else
nn
}
return sampleName
}
apply用法类似run,区别在于apply执行完成block()函数后,返回自身对象
返回自身对象,可以使用链式方法使用.apply{}.apply{}
val adam = Person("Adam").apply {
age = 20
city = "London"
}
let内部使用it指代当前对象,返回最后一行处理结果, (T) -> R
fun testLet(st:String?){
st?.let { // execute this block if not nul
it.plus("-let1")
if(it.startsWith("android"))
it.drop(8)
}
}
val listWithNulls: List<String?> = listOf("element1","element2", null)
for (item in listWithNulls) {
item?.let { // 元素不为空时执行
println(it)
}
}
与let函数相似,区别是also执行完成后返回对象本身,let返回处理结果
fun testAlso() {
val numberList = mutableListOf<Double>()
numberList.also {
println( "init the list")
}.also {
it.add( 2.71)
it.add(3.14)
it.add(1.0)
}.also {
println( "Sorting the list")
}.sort()
}
with函数作用于一个对象,返回最后一行处理结果
fun testWith(){
var p = Person("Tom",26)
//写法一,对象receiver和一个lambda函数块
val result = with(p, {
println("my name is $name, I am $age years old")
1000
})
//由于with函数最后一个参数是一个函数,可以把函数提到圆括号的外部修改后
val result2 = with(p) {
println("my name is $name, I am $age years old")
1000
}
val numbers = mutableListOf("one" , "two","three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("First item: $firstItem, last item:$lastItem")
}
}
函数作为参数
在kotlin中函数可以作为参数传递给另一个函数去执行
例如:
var globalLock = ReentrantLock()
inline fun <T> lockInnerHandle(body: () -> T): T {//统一实现函数线程安全锁
globalLock.lock()
try {
return body()
}
finally {
globalLock.unlock()
}
}
通过这种方式可以统一实现某些功能的形式,简化函数重复代码量,高阶函数 run/apply/let/also等也是将函数作为参数处理的
函数引用
fun isOdd(x: Int) = x % 2 != 0
fun isOdd(s:String) = s =="kotlin"|| s =="java"|| s == "cpp"
fun calLength(s:String ) = s.length
val numbers = listOf(1,2,3)
//normal invoke
println(numbers.filter { isOdd(it) })
//Function References ::调用
println(numbers.filter(::isOdd))
//组合函数使用
fun composeFun(){
val oddLength = compose(::isOdd, ::calLength)//compose(f, g) = f(g(*))
val strings = listOf("a","ab" , "abc" )
println(strings.filter(oddLength))
}
//组合函数定义
fun <A, B, C> compose(f: (B)-> C, g: (A) -> B): (A) -> C {
return { x -> f(g(x)) }
}
//显示指定参数的方法,调用
val predicate: (String) -> Boolean = ::isOdd
predicate("cpp")
//调用类成员
class A(val p:Int)
//调用类的成员方法或扩展方法
val prop = A::p