Kotlin高阶函数中的控制流

Kotlin高阶函数中的控制流

    当你开始使用lambda去替换像循环这样的命令式代码结构时,很快便会遇到return表达式的问题。把一个return语句放在循环的中间是很简单的事情。

1.lambda中的返回语句:从一个封闭的函数返回

    来比较两种不同的遍历集合的方法,在下面代码清单中,很明显如果一个人的名字是Alice,就该从函数lookForAlice返回。

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

    val paple = listOf(Person("Alice", 29), Person("Bob", 31))

    fun lookForAlice(people:List<Person>){
        for (person in people){
            if (person.name=="Alice"){
                LogS("Found!")
                return
            }
        }
    }
    lookForAlice(paple)//Found!

    使用forEach迭代重写这段代码安全吗?return余军还是一样的表现吗?

    是的,正如下面所展示的,使用forEach是安全的。

    fun lookForAlice(people:List<Person>){
        people.forEach {
            if (it.name=="Alice"){
                LogS("Found!")
                return
            }
        }
    }

    如果你在lambda中使用return关键字,它会从调用lambda的函数中返回,并不只是用lambda中返回。这样的return语句叫做非局部返回,因为它从一个比包含return的代码块更大的代码块中返回。

    为了理解这条规则背后的逻辑,想想Java函数中在for循环或者synchronized代码块中使用return关键字。显然会从函数中返回,而不是从循环或者代码块中返回。当使用lambda作为参数的函数的时候Kotlin保留了相同的行为。

2.从lambda返回:使用标签返回

    也可以在lambda表达式中使用局部返回。lambda中的局部返回跟for循环中的break表达式相似。它会终止lambda的执行,并接着从调用lambda的代码处执行。要区分局部返回和非局部返回,要用到标签。想从一个lambda表达式中返回你可以标记它,然后return关键字后面引用这个标签。

  fun lookForAlice(people:List<Person>){
        people.forEach lable@{
            if (it.name=="Alice"){
                return@lable
            }
        }
    }

    要标记一个lambda表达式,在lambda的花括号之前放一个标签名,接着放一个@符号。要从一个lambda返回,在return关键子够放一个@符号,接着放标签名。

    另外一种选择是,使用lambda作为参数的函数的函数名可以作为标签。  

   fun lookForAlice(people:List<Person>){
        people.forEach{
            if (it.name=="Alice"){
                return@forEach
            }
        }
    }

    如果你显示的指定了lambda表达式的标签,再使用函数名作为标签没有任何效果。一个lambda表达式标签数量不能多于一个。

3.匿名函数:默认使用局部返回

    匿名函数是一种不同的用于编写传递给函数的代码块的方式。

    fun lookForAlice(people: List<Person>) {
        people.forEach (
            fun(person) {
                if (person.name == "Alice") {
                    return
                }
            }
        )
    }

    在filter中使用匿名函数

    people.filter(fun (person):Boolean{
        return person.age<30
    })
    匿名函数和普通函数有相同的指定返回值类型的规则。代码块体匿名函数需要显示的指定返回类型,如果使用表达式函数体,就可以省略返回类型。
people.filter(fun (person)=person.age<30)
    在匿名函数中,不带标签的return表达式会从匿名函数中返回,而不是从包含匿名函数的函数返回。这条规则很简单:return从最近的使用fun关键字,所以lambda中的return从最外层的函数返回。匿名函数使用了fun,因此,在前一个例子中匿名函数是最近的符合规则的函数。索引,return表达式从匿名函数返回,而不是从最外层的函数返回。
    尽管匿名函数看起来跟普通函数很相似,但它其实是lamda表达式的另一种语法形式而已。关于lambda表达式如何实现,以及在内联函数中如何被内联的讨论同样适用于匿名函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值