kotlin闭包

  1. 什么是闭包

    一段程序代码通常由变量,常量,表达式组成,然后使用一堆"{}"来闭合,并包裹这些代码,由这对花括号包裹着的代码就是闭包。函数,Lambda,if语句,when语句都可以称之为闭包,但通常情况下我们所说的闭包就是Lambda

    简单的闭包

    fun main() {
        test//yes
    }
    
    val test = if (5 > 3) {
        println("yes")
    } else {
        println("no")
    }
    
  2. 为什么会设计闭包这种结构

    变量的作用域无非就是两种,全局变量和局部变量,使用变量时会从当前作用域向上查找变量,所以函数内部可以直接读取全局变量,而再函数外部自然就无法读取函数内部的局部变量,那么如何读取局部的变量呢?答案就是闭包,这里我们给闭包下一个定义,闭包就是可以读取函数内部变量的函数(参考下面示例)

  3. 普通函数和闭包函数

    普通函数没有状态,调用完毕后里面的内容就会被释放掉

    fun main() {
        test()//3
        test()//3
        test()//3
    }
    
    fun test() {
        var a = 3
        a++;
        println(a)
    }
    

    闭包可以让函数携带状态,闭包捕获的变量可以脱离原始作用域而存在

    fun main() {
        val t = test()//t是个函数Function0,准确的来说是个 函数类型的对象 类似于js的Object和Function
        t()//4 调用t.invoke方法
        t()//5
        t()//6
    }
    
    fun test():()->Unit{//test()函数的返回值是类型为()->Unit的函数类型
       var a = 3//状态
       return fun (){
          a++
          println(a)
       }
    }
    //总结:函数里面声明函数,函数返回值是函数,就是闭包
    //1.函数内部的局部变量的状态保存了,变量的值就是状态
    //2.a被隐藏起来了,但我们可以调用函数改变状态,或者获得a的值。这点就是函数的面向对象,让函数具有封装的能力,让函数具有了状态
    
  4. 自执行闭包

    fun main() {
        {x:Int,y:Int->
            println(x+y)
        }(1,2)//3
    }
    
  5. java于kotlin捕获局部变量的区别

    public interface Clickable {
        void click();
    }
    
    class TestJava {
        private void closure(Clickable clickable){
            clickable.click();
        }
    
        public  void main(ArrayList<String> args) {
            int count = 0;
            closure(()->{
    //            count+=1;//count必须设置为final才能访问,修改count只能把count声明为成员变量
            });
        }
    }
    
    class Test {
        private fun closure(clickable: Clickable){
            clickable.click()
        }
        fun main() {
            var count: Int = 0
           closure(Clickable {
               count+=1//编译正常
           })
            println(count)//1
        }
    }
    
  6. 闭包捕获的变量可以脱离原始作用域而存在

    fun main() {
        //f的类型是(Int)->Int类型,是函数类型的对象,是lambda的引用,lambda的返回值是局部变量total,但是total的作用域是在高阶函数sum中
        //每次执行完f后,total变量的作用域就不存在了,可是total的变量值都能够被保持,由此说明被捕获的变量都存储在一个特殊的容器
        val f = sum()
        println(f(10))
        println(f(10))
        println(f(10))
    }
    
    fun sum():(Int)->Int{//声明高阶函数sum的返回值是(Int)->Int类型
        var total = 0//total是sum高阶函数的局部变量
        return {//使用lambda作为sum()高阶函数的返回值
            total = total+it
            total
        }
    }
    

    文章参考以下文章:

    1. Kotlin函数式编程 (3)✔️闭包与捕获变量
    2. kotlin 闭包简单例子
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin $ 是 Kotlin 语言中的一个特殊语法结构,用于表示代码块或表达式中的闭包。它允许在表达式中定义一个闭包,并在表达式中执行该闭包Kotlin $ 的用法非常灵活,可以用于各种场景,例如函数式编程、控制流、并发编程等。下面是一些常见的用法示例: 1. 定义一个闭包作为函数参数: ```kotlin fun myFunction(doSomething: () -> Unit) { doSomething() } ``` 在这个例子中,`doSomething` 是一个 Kotlin $ 表达式,它定义了一个闭包并传递给 `myFunction` 作为参数。当函数被调用时,闭包将在函数内部执行。 2. 使用 Kotlin $ 进行控制流: ```kotlin fun myProgram() { val counter = object : Counter() { override fun increment() { println("Incremented") } } for (i in 1..5) { counter.increment() println("Loop iteration $i") } } ``` 在这个例子中,`counter` 对象是一个 Kotlin $ 对象,它实现了 `Counter` 接口并重写了 `increment` 方法。在循环中,我们通过调用 `counter.increment()` 来执行闭包,并在每次迭代时打印不同的信息。 3. 使用 Kotlin $ 进行并发编程: ```kotlin fun main() { val semaphore = Semaphore(1) // 创建一个计数器信号量,初始值为1 val tasks = listOf(Task1(), Task2(), Task3()) // 创建三个任务对象 tasks.forEach { task -> semaphore.acquire() // 获取许可,表示任务可以执行 task.execute() // 执行任务 semaphore.release() // 释放许可,表示任务已完成 } } ``` 在这个例子中,我们使用 Kotlin $ 的 `Semaphore` 类来控制并发访问共享资源的数量。我们创建了一个信号量对象 `semaphore` 并将其初始化为1。然后,我们创建了三个任务对象 `Task1`、`Task2` 和 `Task3`。在每个任务开始执行之前,我们使用 `acquire()` 方法获取许可,表示任务可以执行。执行完任务后,我们使用 `release()` 方法释放许可,表示任务已完成。 这只是 Kotlin $ 用法的一部分示例,实际上它可以在许多不同的场景中使用。你可以查阅 Kotlin 官方文档或相关教程来了解更多关于 Kotlin $ 的用法和语法细节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值