Kotlin 函数系列

Kotlin 函数系列

函数

基本使用

Koltin中函数使用fun关键字,函数名紧跟其后。

//代码块函数体
fun add(a: Int, b: Int): Int {
    return a + b
}

//表达式函数
fun add(a: Int, b: Int) = a + b

//可以将lambda表达式存储在一个变量中
val add = { a: Int, b: Int -> a + b }

命名参数

命名参数指在调用函数时传入形参的名。

fun showInfo(name: String, age: Int) {
    println("name:$name,age$age")
}

showInfo("Tom", 18)
showInfo(age = 18, name = "Tom") //命名参数

默认参数

fun showInfo(name: String = "保密", age: Int = 0) {
    println("name:$name,age$age")
}

showInfo()
showInfo(age = 18, name = "Tom")

可变参数

fun showInfo(vararg text: String) {
    text.forEach { println(it) }
}
showInfo("hello", "Android", "Kotlin")

val list = arrayOf("hello", "world")
showInfo(*list)

数组转可变长参数

fun main() {
    val arr = arrayOf("a", "b", "c")
    myfun(*arr)

}

fun myfun(vararg args: String) {
    args.forEach {
        println("- $it")
    }
}
a
b
c

函数类型

  • 函数类型(Function Type)就是函数的类型。
  • 在Kotlin中,函数是一等公民,变量可以有类型,函数也是可以有的。
  • 将函数的“参数类型”和“返回值类型”抽象出来就得到了函数类型。
//  	  (Int,    Int) -> Float   这就是add函数的类型
//			↑ 	    ↑	    ↑
fun add(a: Int, b: Int): Float { 
    return (a + b).toFloat() 
}

说明:这个函数的参数类型是两个Int类型,返回值类型是Float类型,所以函数类型是 (Int, Int) -> Float

Lambda

定义

  • Lambda可以理解为函数的简写
  • Lambda表达式必须用{}包裹
  • Lambda表达式声明了参数和返回值类型,那么Lambda变量可以省略类型声明
  • 返回值为函数体的最后一行代码
{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}

SAM转换

  • SAM是Single Abstract Method的缩写,意思是只有一个抽象方法的类或接口。但在Kotlin和Java 8 中,SAM表示只有一个抽象方法的接口
  • 只要符合SAM要求的接口,编译器就能进行SAM转换,我们可以使用Lambda表达式简写接口类型的参数。
  • 当一个函数的参数是SAM的情况下, 我们即可以用匿名内部类的方式传参,也可以用Lambda方式传参。
//OnClickListener是一个SAM接口
public void setOnClickListener(@Nullable OnClickListener l) {

}

//编译器会SAM转换为
fun setOnClickListener(l: ((View!) -> Unit)?)
//可以传入匿名内部类
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
        println("hello world")
    }
})
//可以传入Lambda表达式
button.setOnClickListener { println("hello world") }

无参数

fun say() {
    println("sayHello")
}

//简化为
val say = { println("sayHello") }

有参数

fun sum(a: Int, b: Int): Int {
    return a + b
}

//等价于
val sum: (Int, Int) -> Int = { a, b -> a + b }

//等价于
val sum = { a: Int, b: Int -> a + b }

lambda表达式可以调用:

lambda.invoke()

匿名函数

fun sum(a: Int, b: Int): Int {
    return a + b
}

//等价于
val sum = fun(a: Int, b: Int): Int {
    return a + b
}

自运行Lambda

val ret = { a: Int, b: Int -> a + b }(1, 2)

高阶函数

如果一个函数的“参数”或者“返回值”的类型是函数类型,那这个函数就是高阶函数。

fun sum(x: Int): (Int) -> Int {
    return { y: Int -> x + y }
}

//等价于
fun sum(x: Int) = { y: Int -> x + y }
//调用
val result = sum(1)(2)

带接收者的函数类型

data class User(val name: String, val age: Int)

//                                       带接收者的函数类型
//                                   ├        ↓          ┤
fun User.operate(msg: String, block: User.(String) -> Unit): User {
    //                                ↑
    //                             接收者类型
    block(msg)
    return this
}

fun main() {
    val user = User("小明", 18)
    user.operate("hello world") {
        println(it)
        println(this)
        println("姓名:${name},年龄:${age}")
    }
}

//hello world
//User(name=小明, age=18)
//姓名:小明,年龄:18

说明:

  • block 是函数类型的变量。
  • block中的 User 是接收者类型。
  • this指接收者类型的对象,通过编译器注入的,是可以被省略的。
  • it 是函数中的唯一参数。

闭包

一个函数内部申明或返回一个函数,那么这个函数称为闭包。

在Kotlin中,变量的作用域只有两种:全局变量和局部变量。

  • 全局变量:函数内部和函数外部都可以直接访问。
  • 局部变量:只有在函数内部可以方位。

闭包的设计就是为了能让开发者在函数外部访问函数内部的局部变量。

fun main() {
    val t = test() //1
    t()//2
    t()//3
}

fun test(): () -> Int {
    var a = 1
    println(a)
    return fun(): Int {
        a++
        println(a)
        return a
    }
}

Kotlin实现接口回调

Java思想实现

//定义接口
interface ICallback {
    fun onSuccess(msg: String)
    fun onError(err: String)
}
//监听事件
class TestCallback {
    private var mCallback: ICallback? = null

    fun setCallback(callback: ICallback) {
        mCallback = callback
    }

    fun test() {
        mCallback?.onSuccess("成功")
        mCallback?.onError("失败")
    }
}
fun main() {
    val testCallback = TestCallback()
    testCallback.setCallback(object : ICallback {
        override fun onSuccess(msg: String) {
            println(msg)
        }

        override fun onError(err: String) {
            println(err)
        }

    })
    testCallback.test()
}

Kotlin高阶函数思想实现

去掉了接口和匿名内部类

class TestCallback {
    private var success: ((String) -> Unit)? = null
    private var error: ((String) -> Unit)? = null

    fun setCallback(success: ((String) -> Unit), error: ((String) -> Unit)) {
        this.success = success
        this.error = error
    }

    fun test() {
        success?.invoke("yes")
        error?.invoke("no")
    }
}
fun main() {
    val testCallback = TestCallback()
    testCallback.setCallback({ println(it) }, { println(it) })
    testCallback.test()
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值