Kotlin 和惯用的书写方式,基于可变值“如果不为空,则...”

2024-05-16

假设我们有这样的代码:

class QuickExample {

    fun function(argument: SomeOtherClass) {
        if (argument.mutableProperty != null ) {
            doSomething(argument.mutableProperty)
        } else {
            doOtherThing()
        }
    }

    fun doSomething(argument: Object) {}

    fun doOtherThing() {}
}

class SomeOtherClass {
    var mutableProperty: Object? = null
}

与 Java 不同,在 Java 中,您可以独自担心运行时空取消引用,这不会编译 - 完全正确。当然,mutableProperty一旦在“if”内,就不再为空。

我的问题是处理这个问题的最佳方法是什么?

有几个选项是显而易见的。在不使用任何新的 Kotlin 语言功能的情况下,最简单的方法显然是将值复制到随后不会更改的方法范围内。

有这个:

fun function(argument: SomeOtherClass) {
    argument.mutableProperty?.let {
        doSomething(it)
        return
    }
    doOtherThing()
}

这有一个明显的缺点,您需要提前返回或以其他方式避免执行后续代码 - 在某些小型上下文中可以,但有味道。

那么就有这样一种可能:

fun function(argument: SomeOtherClass) {
    argument.mutableProperty.let {
        when {
            it != null -> {
                doSomething(it)
            }
            else -> {
                doOtherThing()
            }
        }
    }
}

尽管它的目的更加明确,但可以说它比 Java 风格的处理方式更加笨拙和冗长。

我是否遗漏了什么,是否有一个首选的习惯用法可以实现这一点?


Update:

正如弗兰塔在评论中提到的,如果该方法doSomething()返回 null,然后将执行 elvis 运算符右侧的代码,这可能不是大多数人想要的情况。但同时,在这种情况下,很可能doSomething()方法只会做一些事情,不会返回任何东西。

还有一种替代方案:正如 Protossor 在评论中提到的那样,also可以使用而不是let, 因为also回报this对象而不是功能块的结果。

mutableProperty?.also { doSomething(it) } ?: doOtherThing()

原答案:

我会用let with 埃尔维斯操作员 https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator.

mutableProperty?.let { doSomething(it) } ?: doOtherThing()

来自文档:

如果 ?: 左边的表达式不为 null,则 elvis 运算符 返回它,否则返回右侧的表达式。笔记 仅当左侧表达式成立时才计算右侧表达式 边为空。

对于右侧表达式之后的代码块:

   mutableProperty?.let {
            doSomething(it)
        } ?: run {
            doOtherThing()
            doOtherThing()
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kotlin 和惯用的书写方式,基于可变值“如果不为空,则...” 的相关文章

  • Android Toast 消息不起作用

    我正在通过 Andengine 为 Android 开发游戏 我有 MainActivity 类和 GameScene 类 我在 GameActivity 中使用 Toast 消息 它正在发挥作用 Toast makeText this H
  • 如何使全屏覆盖在方向更改后保持全屏?

    我正在制作一个应用程序 它可以创建在屏幕上行走的微小精灵动画 我有一个主要活动 带有 启动服务 按钮 这会启动一个服务 该服务 在onCreate 创建一个全屏视图并将其附加到根窗口管理器 这部分工作完美 它充满了屏幕 您可以离开应用程序
  • 处理 SavedInstances 并恢复活动

    基本上我的应用程序有 2 个活动 说 A 和 B A 启动 B Activity B 播放音乐并且还有通知 情况 1 当视图仍在活动 B 上时 我按主页按钮 然后单击通知 活动 B 将打开 其视图完好无损并播放音乐 因为在清单中我使用 an
  • 单击另一个项目/小部件时展开/打开微调器?

    当用户单击另一个按钮时 我试图展开微调器 例如 我有一个带有值的微调器和一个 确定 按钮 当用户单击 确定 按钮而不从微调器中选择任何值时 微调器会自行扩展 是否可以在无需用户与微调器交互的情况下获得扩展微调器的事件 只需致电Spinner
  • 如何在 Kotlin 中的数据类上实现空对象模式?

    我有一个 Kotlin 数据类 data class PaymentAccount val accountId Int val accountNumber String val title String 这就是我在 Java 中要做的事情
  • 简单 XML 框架:ElementMap 中的对象具有“类似内联”的行为

    我正在尝试在 Android 上序列化自定义对象的 Hashmap 以获得如下 xml
  • 如何在 Android 中的 Chrome 或 Firefox 等特定浏览器的 Web 视图中加载应用程序

    我是 Android 新手 我正在做一个应用程序 我需要在平板电脑上的 Web 视图中加载现有的应用程序 在平板电脑中 当我使用 Web 视图加载应用程序时 我的应用程序将加载到默认浏览器中 如何在平板电脑上的 Web 视图中的特定浏览器
  • animation.start() 或animation.startNow() 不会立即开始动画

    我有一个奇怪的问题 有时应该淡出我的控件 ImageButton 的动画不会立即启动 我使用淡出动画来隐藏它 然后在 myListener 的末尾 onAnimationEnd 中 我将新资源作为按钮上的图像 我的应用程序代码中的某处 An
  • 如何使用onDraw(Canvas)获取WebView的位图快照(Android)

    我曾经使用 capturePicture 方法来制作 WebView 的快照 此方法在 API 级别 19 中已弃用 该文档说 使用 onDraw Canvas 获取 WebView 的位图快照 但我真的不知道它是什么意思 你能教我如何解决
  • 如何检查 Android 设备是否在线

    我的服务器不断检查我的 Android 应用程序是否在线 请问我可以在我的android应用程序上执行哪些操作 创建一个名为 isNetworkAvailable 的帮助器方法 该方法将根据网络是否可用返回 true 或 false 它看起
  • NDK8d 未找到 std::string 操作(即 stol、stoi)

    我尝试使用 ndk r8d 和 c 11 支持来建立我的第一个 android 项目 一些 c 11 机制工作正常 即 lambda 表达式 但是当我尝试时 使用新的字符串操作之一 编译失败 错误 stol 不是 std 的成员 这是我的
  • 返回到上一个活动的最后状态

    我有两个活动 A 和 B 当应用程序启动时 活动 A 会被加载 我会从数据库将数据加载到其中 我可以毫无问题地转到活动 B 但是当我返回活动 A 时 会查看旧数据一段时间 然后重新加载活动 知道如何解决这个问题吗 在从数据库加载数据之前清除
  • 如何使用 let (或 apply 等)检查 2 个条件

    有没有更惯用的方式来编写以下内容 foo let if foo isBlank bar let if bar isBlank println foo and bar both valid strings 基本上这个想法是两个字符串都应该是非
  • Android 应用程序不需要任何特殊访问权限

    当我开始安装时myapp apk 我得到下面的屏幕 我的应用程序需要位置 外部存储权限 上述权限应该根据需要向用户请求 即在需要这些权限的代码之前 现在 当安装应用程序时 我会看到一个屏幕 上面显示应用程序不需要任何特殊访问权限 如下图所示
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • Android 导航组件 - 从“任何地方”/基本片段导航?

    我正在开发一个应用程序 它有一个奇怪的花招 可以在设备旋转时打开特定的片段 在实现 android 的导航组件之前 所需要的只是对当前活动的引用 并且可以在特定时刻向用户显示的任何内容之上执行手动片段事务 但是在转移到导航组件之后 我发现很
  • Android 中的 ODEX 文件是什么?

    经过一些android安装了应用程序 我发现它会变成odex文件 不是apk 在智 能手机中 这是怎么发生的 谁能教教我 我对此很感兴趣 博客文章 https stackoverflow com a 9593590 194894大部分是正确
  • 如何在android中将文本放在单选按钮的左侧

    我想将单选按钮的文本放在左侧而不是右侧 我找到了这个解决方案
  • Recyclerview项目点击涟漪效果[重复]

    这个问题在这里已经有答案了 我正在尝试添加Ripple影响到RecyclerView的项目 我在网上查了一下 但找不到我需要的东西 我努力了android background归因于RecyclerView本身并将其设置为 android
  • 从 Dropbox 下载文件并将其保存到 SDCARD

    现在我真的很沮丧 我想从 Dropbox 下载一个文件并将该文件保存到 SD 卡中 我得到的代码为 private boolean downloadDropboxFile String dbPath File localFile throw

随机推荐

  • QTimer 一点也不准确?

    运行在 Windows7 64 位机器上 具有非常强大的 CPU 8 核 16 线程 我使用 QTimer 以 50Hz 触发函数调用 但我最终得到了 30Hz 函数调用本身肯定需要不到 10 毫秒才能完成 整个过程发生在一个单独的线程中
  • Fluent NHibernate - 将属性映射到连接表上的列

    我有几张桌子 例如 产品 Id 名称 制造商 ID 制造商 ID 名称 我希望能够在我的产品对象上包含ManufacturerName 而不是当我只需要名称时必须加载整个制造商行 我的产品地图看起来像 Table Product Id x
  • opencv人脸检测示例

    当我在设备上运行应用程序时 应用程序崩溃并显示以下按摩 java lang UnsatisfiedLinkError 无法加载 detector based tracker findLibrary 返回 null 我正在使用 OpenCV
  • JSPX 命名空间对于 EL 函数不可见?

    我正在尝试使用 JSPX JSP 的纯 XML 语法 并遇到看起来应该可以工作但实际上却不起作用的情况 我使用 jsp root 元素中的命名空间声明导入标签库 然后稍后将这些用于元素以及 EL 函数
  • 在 jTextfield 中禁用“粘贴”

    我有一个用 Swing awt 编写的应用程序 我想阻止用户将值粘贴到文本字段中 有没有办法在不使用动作监听器的情况下做到这一点 您可以使用 null 参数调用 setTransferHandler 如下所示 textComponent s
  • 如何在 VB.NET 中声明和初始化多维数组?

    我想做这个 Dim Numbers As Integer 1 2 3 4 5 6 7 IDE 的下划线4 5 6 7并说Array initializer has 3 too many elements 我究竟做错了什么 以下应该有效 Di
  • 面部标记信息和照片元数据

    是否有一种标准方法可以从照片元数据中读取 写入面部标签 我可以用它从流行的照片管理器导入面部标记信息吗 Yes 元数据工作组 即 Adob e Microsoft Sony Nokia 等 已经开发了 XMP 的标准扩展来实现此目的 请参阅
  • 从 WP8 连接至 Polar H7 心率监测器

    有没有办法从 Windows Phone 8 连接到低功耗蓝牙设备 例如心率监测器 例如 Polar H7 我尝试过的一些背景 我看过这个 Windows 8 的示例 http code msdn microsoft com windows
  • Angular2 viewContainerRef.createComponent 工作正常

    我使用 viewContainerRef createComponent 将动态组件加载到根组件 但实际上它附加了错误的位置 my code app compoment ts export class AppComponent privat
  • Rails、REST 架构和 HTML 5:带有预检请求的跨域请求

    在致力于使我们的网站 HTML 5 友好的项目时 我们渴望采用跨域请求的新方法 不再通过隐藏的 iframe 发布 使用访问控制 http www w3 org TR access control 根据规范 我们开始设置一些测试来验证各种浏
  • 使用 Spring 的 REST 多部分混合请求(文件+json)

    我需要将一个文件和一个 json 一起发送到我的 Spring 控制器 我有以下控制器类 Controller RequestMapping perform public class PerformController RequestMap
  • SQL Server 批量插入 - “批量加载数据转换错误”

    bulk insert dbo A FROM d AData csv WITH FIELDTERMINATOR ROWTERMINATOR n 将批量数据插入数据库时 在检查可疑数据后 我遇到了无法解释的错误 消息 4867 16 级 状态
  • 对象数组的数组(二维数组)JNI

    我正在努力创建自定义对象类型 ShareStruct 的二维数组 jobjectArray ret jobjectArray ins jobjectArray outs jclass myClass env gt FindClass env
  • 如何从子窗体访问winforms父窗体控件

    在 Form1 中 我有一个 DataGridView 和多个文本框 当我单击 Form2 中的 A 按钮时 我需要将 DataGridView 和多个文本框中的数据保存到数据库中 如何在C Sharp Windows应用程序中实现 For
  • 如何为没有物理根的平面项目进行 Gradle 设置

    我们正在迁移到 Rational Team Concert RTC 并希望利用它的 组件 定义 流中使用的组件会产生一个平坦的本地 scm 工作空间 并且其物理根不在 scm 中 如下所示 workspace name component1
  • IE7 和 TinyMCE 与 Plone

    在 Windows 服务器上开箱即用的 Plone 4 1 4 4113 中 IE7 上会出现一些客户端问题 我知道 访问主站点 没问题 登录 IE 引发运行时错误 第 505 行 扩展标识符 字符串或数字 添加内容 IE 引发运行时错误
  • 如何从 Gforth 网站读取原始代码?

    我想要一个像这样的词 read site add n buff max n flag 其中 add n 是站点名称缓冲区 buff max 是应读取 ASCII 文本的缓冲区 n 是读取的字节数 flag如果操作成功则为 true 这在 L
  • 覆盖 logback 配置

    有什么方法可以覆盖 logback 配置吗 我知道我们在名为的文件中定义了 logback 配置logback xml 通常存储在路径中src main resources 并且我知道通过使用
  • 使类只能从特定类实例化

    假设我有 3 节课class1 class2 and class3 我怎样才能拥有它class1只能通过实例化class2 class1 object new class1 但不是 class3 或任何其他类 我认为它应该与修饰符一起使用
  • Kotlin 和惯用的书写方式,基于可变值“如果不为空,则...”

    假设我们有这样的代码 class QuickExample fun function argument SomeOtherClass if argument mutableProperty null doSomething argument