为什么 use 块不能安全地初始化 var?

2023-12-29

为什么这会出现编译错误?

val autoClosable = MyAutoClosable()
var myVar: MyType
autoClosable.use {
    myVar= it.foo()
}
println(myVar) // Error: Variable 'myVar' must be initialized

也许编译器只是看到{ myVar= it.foo() }作为传递给另一个函数并且不知道何时或是否会执行的函数?

但是由于use不仅仅是一个函数,而是 Kotlin 替代 Java 的 try-with-resource,了解一些关于它的特殊知识是合适的,不是吗?现在,我被迫初始化myVar带有一些虚拟值,这根本不符合 Kotlin 的精神。


Since use { ... }不是一种语言结构,而是只是一个库函数 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html,编译器不知道(并且目前不努力证明)您传递的 lambda 是曾经被处决。因此,禁止使用可能未初始化的变量。

例如,将您的代码与此函数调用进行比较。无需额外的代码分析,它们对于编译器来说是相同的:

inline fun ignoreBlock(block: () -> Unit) = Unit

var myVar: MyType
ignoreBlock { myVar = it.foo() }
println(myVar) // Expectedly, `myVar` stays uninitialized, and the compiler prohibits it

要绕过此限制,您可以使用从返回的值use(这是您的块返回的值)来初始化您的变量:

val myVar = autoClosable.use {
    it.foo()
}

如果您还想处理它可能抛出的异常,那么使用try作为一个表达 https://kotlinlang.org/docs/reference/exceptions.html#try-is-an-expression:

val myVar = try {
    autoClosable.use {
        it.foo()
    }
} catch (e: SomeException) {
    otherValue   
}

理论上,内联函数实际上可以被检查以调用 lambda 一次,如果 Kotlin 编译器可以做到这一点,它将允许您的用例和其他一些用例。但这尚未实施。

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

为什么 use 块不能安全地初始化 var? 的相关文章

随机推荐

  • 字段初始化

    下面两种字段初始化方式有什么区别吗 什么时候使用哪一个 第一种方式 public class Class1 private SomeClass someclass public Class1 someclass new SomeClass
  • 程序不包含适合 .Net MAUI Xunit 中入口点的静态“Main”方法

    我正进入 状态 程序不包含适合入口点的静态 Main 方法 在 NET MAUI 中运行 Xunit 项目时出错 public class UnitTest1 Fact public void Test1 重现 创建一个 MAUI 应用程序
  • JavaFX setOnEndOfMedia 在下一个 MediaPlayer 上

    I have List
  • 更改ASP.net core 3.0中的身份登录URL

    我正在尝试更改默认登录 URL Identity Account Login to Login 我查过类似的问题 他们提出了与此类似的解决方案 public void ConfigureServices IServiceCollection
  • 流式传输 Android 屏幕

    我正在尝试休憩Truiton 屏幕捕捉 https github com Truiton ScreenCapture例如 为了记录设备屏幕使用媒体投影 https developer android com reference androi
  • SAS - 使用另一列中的值动态创建列名称

    我有一列包含许多从 XML 解析器解析的标志 数据如下 USERKEYED Y VALMATCH N DEVICEVERIFIED N EXCEPTION N USERREGISTRD N ASSOCIATE Y EXTERNAL N GR
  • 谁能发布一个如何在 Tsung 中启用 SSL 的示例?

    我正在使用 Tsung 从另一台计算机对 CouchDB 服务器进行负载测试 并且需要建立安全连接 不幸的是 我无法在文档或在线中找到语法示例 任何帮助将不胜感激 在 tsung xml 中
  • 如何让移动浏览器(iOS、Android 中的 webkit)显示其软键盘

    我正在编写一个小型 Web 应用程序 它大量使用 canvas 元素来执行类似于 VNC 的操作 它特别针对 iOS 和 Android 的默认浏览器 我可以通过 AJAX 调用检测何时需要键盘输入 但我无法说服移动浏览器按需显示其软键盘
  • 如何在 Azure Key Vault 中存储公共证书(.cer 文件)

    如何在 azure keyvault 中上传或存储公钥 cer 文件 当我尝试上传适用于 pfx 文件的任何 cer 文件时 从 keyvault 面板中会出现错误 您应该考虑 Key Vault 是否适合您的场景 公钥 本质上 不是机密数
  • cscope支持历史列表记录吗?

    I use C要获取一个函数的调用者 那么我可以按一个数字跳转到一个调用者 但如果我想跳到另一个来电者 我必须按跳回 再按C 即可获取来电列表 cscope支持历史列表记录吗 如果您使用VIM 可以尝试快速修复 se cscopequick
  • Haskell 中的“约束”是什么意思

    我对 Haskell 很陌生 我正在尝试通过编写一些代码来理解该语言 我只熟悉 ghci 上非常简单的指令 head tail sum 等 非常简单 我试图创建的函数是为了求解任意维向量的毕达哥拉斯定理 这看起来像这样 平方根 a 2 b
  • 词法作用域是如何实现的? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 几年前 我开始为一种小型领域特定语言编写解释器 其中包括程序员定义的函数 起初 我使用简单的符号表堆栈
  • 词集中词的最大交集算法

    背后的故事 我正在使用创建语音控制应用程序x webkit speech这是令人惊讶的好 功能 而不是我的应用程序 但有时用户 我 会有点咕哝 如果单词的某些合理部分与某些合理命令的某些合理部分相匹配 那么接受该命令会很好 所以我寻找名为
  • Numpy 提取子矩阵

    我是新来的numpy我很难理解如何从np array具有定义的列和行的子矩阵 Y np arange 16 reshape 4 4 如果我想提取列 行 0 和 3 我应该 0 3 12 15 我尝试了所有的重塑功能 但不知道如何做到这一点
  • 在没有准备好的语句/SQLite/C++ 的情况下防止 SQL 注入

    我希望得到一些有关此方案针对 SQL 注入攻击的安全性的反馈 在前端 用户输入个人信息 姓名 地址 电话号码 电子邮件和一些自由格式文本 后端是用C 从头开始编码的 没有框架支持 并集成了SQLite C 代码是这样的not使用 SQLit
  • 简单易懂的 Spring 应用程序登录

    我对 Spring 很陌生 今天才开始学习 我一直在寻找一个简单的登录应用程序 它也将解释 Spring 之外的应用程序的流程 当我用谷歌搜索时 我真的找不到其中的几个 http viralpatel net blogs tutorial
  • 将行号添加到 SQL 查询的结果集中

    我有一个简单的选择语句 我想添加一个临时列来表示结果集中的行数 我尝试过这个 declare num int set num 0 select t A t B t C count 1 as number from tableZ as t 它
  • 如何使用 LocationCollection 缩放以适应 WP7 Bing Maps 控件?

    如何在 Windows Phone 7 上将 Microsoft Phone Controls Maps Map 控件缩放到正确的缩放级别 我有一个地理坐标的 LocationCollection 并且我自己计算了中心 但现在如何计算正确的
  • EntityFramework连接问题

    我在 Visual Studio 2008 中有一个包含 3 个项目的解决方案 1 个 Web 应用程序和 2 个类库 实体框架模型位于类库中 起始项目是 Web 应用程序 我曾经遇到过这样的问题 在配置中找不到指定的命名连接 不适合与 E
  • 为什么 use 块不能安全地初始化 var?

    为什么这会出现编译错误 val autoClosable MyAutoClosable var myVar MyType autoClosable use myVar it foo println myVar Error Variable