前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【错误记录】Kotlin 中 Lambda 表达式返回值报错 ( ‘return‘ is not allowed here | 匿名内部类 | 尾随 Lambda 规范 - Lambda 替换接口 )

【错误记录】Kotlin 中 Lambda 表达式返回值报错 ( ‘return‘ is not allowed here | 匿名内部类 | 尾随 Lambda 规范 - Lambda 替换接口 )

作者头像
韩曙亮
发布2024-04-20 08:36:47
690
发布2024-04-20 08:36:47
举报

一、错误记录

在 Android 中 , 使用 Kotlin 开发 , 为 BottomNavigationView 设置 OnNavigationItemSelectedListener 监听接口 ;

设置的接口是一个匿名内部类 BottomNavigationView.OnNavigationItemSelectedListener 对象 , 其中定义了一个

代码语言:javascript
复制
boolean onNavigationItemSelected(@NonNull MenuItem var1); 

函数 , 需要返回一个布尔值 ;

直接使用 return 返回布尔值 , 就报如下错误 ;

二、问题分析

1、匿名内部类

BottomNavigationView 调用 setOnNavigationItemSelectedListener 函数 , 设置的监听器是 BottomNavigationView.OnNavigationItemSelectedListener 类型的匿名内部类 ;

最原始的设置方式如下 , 首先创建 BottomNavigationView.OnNavigationItemSelectedListener 类型的 对象表达式 , 也就是匿名内部类 , 然后 调用 setOnNavigationItemSelectedListener 函数将其设置给 BottomNavigationView 作为 选择监听器 ;

代码语言:javascript
复制
        // 创建匿名内部类
        val listener = object : BottomNavigationView.OnNavigationItemSelectedListener {
            override fun onNavigationItemSelected(p0: MenuItem): Boolean {
                return false
            }
        }
        // 设置匿名内部类参数
        navView.setOnNavigationItemSelectedListener(listener)

在上一步的基础上 , 可以不进行声明 , 直接设置 匿名内部类 , 如下代码所示 :

代码语言:javascript
复制
        // 直接设置匿名内部类
        navView.setOnNavigationItemSelectedListener(object : BottomNavigationView.OnNavigationItemSelectedListener {
            override fun onNavigationItemSelected(p0: MenuItem): Boolean {
                return false
            }
        })

2、尾随 Lambda 规范 - Lambda 替换接口

参考博客 【Kotlin】Kotlin 中使用 Lambda 表达式替代对象表达式原理分析 ( 尾随 Lambda - Trailing Lambda 语法 | 接口对象表达式 = 接口#函数类型对象 ) , 符合 尾随 Lambda 表达式的要求 , 最后一个函数是匿名内部类 , 匿名内部类中只实现了一个函数 , 此时使用 Lambda 表达式替代该 匿名内部类 ;

Lambda 表达式 其本质 就是 函数类型 的 匿名对象 , 也是一个实例对象 , 在堆内存中分配相应的空间 ;

在下面的代码中 , 使用 对象表达式 创建了匿名对象 , 该匿名类实现了 BottomNavigationView.OnNavigationItemSelectedListener 接口 , 并实现了其中的 onNavigationItemSelected 函数 ;

代码语言:javascript
复制
object : BottomNavigationView.OnNavigationItemSelectedListener {
	override fun onNavigationItemSelected(p0: MenuItem): Boolean {
		return false
	}
}

符合以下两个条件 :

  • 函数 接收一个 接口类型 的匿名内部类 或 对象表达式 ;
  • 该 接口类型 中 只定义了一个函数 ;

可以 省略掉 匿名内部类 也就是 对象表达式的定义 , 直接使用 接口中的函数 类型对象 , 也就是 Lambda 表达式 / 匿名函数 / 闭包 来替代该 接口类型 变量 ;

省略后的简写方式如下 :

代码语言:javascript
复制
        // Lambda 替换对象表达式
        navView.setOnNavigationItemSelectedListener {
            return@setOnNavigationItemSelectedListener false
        }

3、Lambda 表达式中 return 需要 @ 标签

这里特别注意 :

在 Kotlin 中 , 在 lambda 表达式或匿名函数中使用 return 语句时 , 必须使用 return@label 语法来指定你要返回的标签 ;

在 Kotlin 中 , return 语句默认是从最近的封闭函数返回的 , 而在 lambda 表达式中使用 return 时 , 它会尝试从包含它的函数返回 ;

三、解决方案

在 Lambda 表达式的 return 返回时 , 添加 @ 标签 , 不能直接使用 return 进行返回 ;

代码语言:javascript
复制
        // Lambda 替换对象表达式
        navView.setOnNavigationItemSelectedListener {
            return@setOnNavigationItemSelectedListener false
        }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、错误记录
  • 二、问题分析
    • 1、匿名内部类
      • 2、尾随 Lambda 规范 - Lambda 替换接口
        • 3、Lambda 表达式中 return 需要 @ 标签
        • 三、解决方案
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档