如果值是 `let` 常量,为什么我只能直接使用元组名称附加元组数组 - Swift

2024-03-07

这是我正在谈论的一个例子:

typealias SomeTuple = (string: String, int: Int)

var tupleArray: [SomeTuple] = []

// Fails
// tupleArray.append(string: "Hello", int: 42)

// Works
let string = "Hello"
let num = 42
tupleArray.append(string: string, int: num)

// Fails
// var varString = "Hi Again"
// var varNum = 234
// tupleArray.append(string: varString, int: varNum)

为什么.append(tupleName: val, anotherTupleName: anotherVal)语法仅在之前将值声明为let常数?

Note:

我知道我可以将元组包装在额外的括号中,如下所示:

tupleArray.append((string: "Hey", int: 234))

我的问题是为什么我不必这样做let常数。


swiftc -dump-ast揭示了一些可能的原因。

让我们从简化的代码开始:

let string = "Hello"
let num = 42
var varString = "Hi Again"
var varNum = 234 

typealias SomeTuple = (string: String, int: Int)
func foo(x:SomeTuple) {}

错误案例

foo(string: "Hello", int: 42)
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=test.swift:9:1 range=[test.swift:9:1 - line:9:29]
        (declref_expr type='(SomeTuple) -> ()' location=test.swift:9:1 range=[test.swift:9:1 - line:9:1] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:2:6 specialized=no)
        (tuple_expr type='<<error type>>' location=test.swift:9:4 range=[test.swift:9:4 - line:9:29] names=string,int
          (string_literal_expr type='<<error type>>' location=test.swift:9:13 range=[test.swift:9:13 - line:9:13] encoding=utf8 value="Hello")
          (integer_literal_expr type='<<error type>>' location=test.swift:9:27 range=[test.swift:9:27 - line:9:27] value=42))))

在这种情况下,编译器无法推断最终类型string_literal_expr and integer_literal_expr. string_literal_expr can be String, StaticString, Selector或诸如此类。

foo(string: varString, int: varNum)
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=test.swift:10:1 range=[test.swift:10:1 - line:10:35]
        (declref_expr type='(SomeTuple) -> ()' location=test.swift:10:1 range=[test.swift:10:1 - line:10:1] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:2:6 specialized=no)
        (tuple_expr type='(string: @lvalue String, int: @lvalue Int)' location=test.swift:10:4 range=[test.swift:10:4 - line:10:35] names=string,int
          (declref_expr type='@lvalue String' location=test.swift:10:13 range=[test.swift:10:13 - line:10:13] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:6:5 direct_to_storage specialized=no)
          (declref_expr type='@lvalue Int' location=test.swift:10:29 range=[test.swift:10:29 - line:10:29] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:7:5 direct_to_storage specialized=no))))

在这种情况下,编译器解释为(string: varString, int: varNum) as (string: @lvalue String, int: @lvalue Int)。并且它不匹配(string: String, int: Int).

成功案例

foo(string: "Hello" as String, int: 42 as Int)
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=test.swift:13:1 range=[test.swift:13:1 - line:13:46]
        (declref_expr type='(SomeTuple) -> ()' location=test.swift:13:1 range=[test.swift:13:1 - line:13:1] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:2:6 specialized=no)
        (tuple_expr type='(string: String, int: Int)' location=test.swift:13:4 range=[test.swift:13:4 - line:13:46] names=string,int
          (coerce_expr type='String' location=test.swift:13:21 range=[test.swift:13:13 - line:13:24] writtenType=String
            (call_expr implicit type='String' location=test.swift:13:13 range=[test.swift:13:13 - line:13:13]
              (constructor_ref_call_expr implicit type='(_builtinStringLiteral: RawPointer, byteSize: Word, isASCII: Int1) -> String' location=test.swift:13:13 range=[test.swift:13:13 - line:13:13]
                (declref_expr implicit type='String.Type -> (_builtinStringLiteral: RawPointer, byteSize: Word, isASCII: Int1) -> String' location=test.swift:13:13 range=[test.swift:13:13 - line:13:13] decl=Swift.(file).String.init(_builtinStringLiteral:byteSize:isASCII:) specialized=no)
                (type_expr implicit type='String.Type' location=test.swift:13:13 range=[test.swift:13:13 - line:13:13] typerepr='<<IMPLICIT>>'))
              (string_literal_expr type='(_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1)' location=test.swift:13:13 range=[test.swift:13:13 - line:13:13] encoding=utf8 value="Hello")))
          (coerce_expr type='Int' location=test.swift:13:40 range=[test.swift:13:37 - line:13:43] writtenType=Int
            (call_expr implicit type='Int' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37]
              (constructor_ref_call_expr implicit type='(_builtinIntegerLiteral: Int2048) -> Int' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37]
                (declref_expr implicit type='Int.Type -> (_builtinIntegerLiteral: Int2048) -> Int' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37] decl=Swift.(file).Int.init(_builtinIntegerLiteral:) specialized=no)
                (type_expr implicit type='Int.Type' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37] typerepr='<<IMPLICIT>>'))
              (tuple_expr implicit type='(_builtinIntegerLiteral: Int2048)' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37] names=_builtinIntegerLiteral
                (integer_literal_expr type='Int2048' location=test.swift:13:37 range=[test.swift:13:37 - line:13:37] value=42)))))))

显式转换原因coerce_expr。它构建了String and Int正确。

 foo(string: string, int: num)
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=test.swift:12:1 range=[test.swift:12:1 - line:12:29]
        (declref_expr type='(SomeTuple) -> ()' location=test.swift:12:1 range=[test.swift:12:1 - line:12:1] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:2:6 specialized=no)
        (tuple_expr type='(string: String, int: Int)' location=test.swift:12:4 range=[test.swift:12:4 - line:12:29] names=string,int
          (declref_expr type='String' location=test.swift:12:13 range=[test.swift:12:13 - line:12:13] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:4:5 direct_to_storage specialized=no)
          (declref_expr type='Int' location=test.swift:12:26 range=[test.swift:12:26 - line:12:26] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:5:5 direct_to_storage specialized=no))))

let常数是String and Int, 它没有@lvalue。因此它们可以按原样应用。

foo((string: varString, int: varNum))
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=test.swift:15:1 range=[test.swift:15:1 - line:15:37]
        (declref_expr type='(SomeTuple) -> ()' location=test.swift:15:1 range=[test.swift:15:1 - line:15:1] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:2:6 specialized=no)
        (paren_expr type='(SomeTuple)' location=test.swift:15:5 range=[test.swift:15:4 - line:15:37]
          (tuple_expr type='(string: String, int: Int)' location=test.swift:15:5 range=[test.swift:15:5 - line:15:36] names=string,int
            (load_expr implicit type='String' location=test.swift:15:14 range=[test.swift:15:14 - line:15:14]
              (declref_expr type='@lvalue String' location=test.swift:15:14 range=[test.swift:15:14 - line:15:14] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:6:5 direct_to_storage specialized=no))
            (load_expr implicit type='Int' location=test.swift:15:30 range=[test.swift:15:30 - line:15:30]
              (declref_expr type='@lvalue Int' location=test.swift:15:30 range=[test.swift:15:30 - line:15:30] decl=test.(file)[email protected] /cdn-cgi/l/email-protection:7:5 direct_to_storage specialized=no)))))))

在这种情况下,相比foo(string: varString, int: varNum), load_expr被插入,并且它转换@lvalue String to String, and @lvalue Int to Int

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

如果值是 `let` 常量,为什么我只能直接使用元组名称附加元组数组 - Swift 的相关文章

随机推荐

  • 如何使用 Powershell 枚举 IIS 网站并查找每个网站的应用程序池?

    我可以使用以下方式搜索网站 Get WmiObject Namespace root WebAdministration Class Site Authentication PacketPrivacy ComputerName server
  • 使用 CUDA 生成排列

    我正在阅读有关 CUDA 的内容 我尝试实现一个简单的代码来创建每个可能的排列array a b c d 但我不知道如何实现 CUDA 方式 因为我读到的所有示例都是这种形式a blockIdx x b blockIdx x c block
  • Xcode 无法使用 Apple ID 登录

    最近我想用Xcode归档我的App 然后Xcode说我必须再次输入我的Apple ID和密码 也许我的登录信息丢失了 我又尝试了一次 但总是失败 If I input a wrong password I get a correct res
  • 堆管理

    我知道有一个元数据存储在期间使用的辅助信息free realloc 当我们只提供指针时 我对堆几乎没有疑问 堆栈是按进程分配的 毫无疑问 但对堆不确定 无论堆信息是全局维护的 还是每个进程都会有某种机制来保存有关为该特定进程分配的内存的信息
  • Nose 未运行 Django 文档测试

    如同这个问题 https stackoverflow com questions 2614363 why isnt django nose running the doctests in my models 然而 就我而言 我的模型都没有d
  • Facebook 个人资料 ID 和 uid 之间有区别吗?

    我有一个应用程序 我通过以下代码片段获取应用程序用户的 Facebook uid FB login function response if response authResponse FB getLoginStatus function
  • 如何使用 Dagger2 在 ViewModel 中注入依赖项

    我正在尝试在现有项目中实现新的架构 MVVM RxJava2 Dagger2 Retrofit 我已经建立了整个上述架构并在 HomeActivity 上进行了测试 HomeViewModel 中注入的依赖项 所以现在我试图在Fragmen
  • 在 php 中统计 mongodb

    我有一个集合用户 它有2个参数 用户名 付费 用户名是一个字符串 付费也是一个字符串 我应该计算有多少个带有参数paid true 的用户 这是我的尝试 如果有 mongo 专家可以帮忙 谢谢 新驱动没有实现 cursor gt count
  • 仅使用 CSS 突出显示表行中的所有行跨度

    有没有办法让 CSS 突出显示整行 包括行跨度内的单元格 而不仅仅是第一行 正如你从示例中看到的 只有该行的第一行被突出显示 而其他单元格没有突出显示 这显然看起来很混乱 我宁愿只使用 CSS 来清除它 但如果有的话会使用 Javascri
  • 将正则表达式与 NSPredicate 结合使用

    Aim Using NSPredicate我想使用正则表达式来匹配所有以 Test 开头的字符串 我特别想用Regex and NSPredicate 问题 我犯了什么错误 使用正则表达式来实现我想要做的事情的正确方法是什么 代码 我的尝试
  • 从 Git 存储库克隆后的 Laravel Sail

    我目前有自己的 Laravel 应用程序在 Docker 上运行 在 Windows 11 上使用 Laravel sail 在 WSL2 上使用 Ubuntu 这工作正常并且符合预期 我已将我的工作推送到 Git 存储库 但如何将其拉到新
  • 添加页面时,refinerycms 不工作

    尝试使用 RefineryCMS 从仪表板添加新页面时出现此错误 SQLite3 ConstraintException refinery page translations refinery page id 不得为 NULL INSERT
  • FtpWebRequest ListDirectory 不返回所有文件

    我正在尝试从包含大约 9000 个文件的 FTP 位置检索文件列表 但下面的代码总是只给出 97 个文件 在第 98 个文件的循环开始时 StreamReader Peek 变为 1 输出 test txt 始终仅包含前 97 个文件 就像
  • 创建没有版本号的 Grails 3 WAR

    在 Grails 2 中 我们可以像这样定义 WAR 文件名 grails project war file target appName war 如何覆盖 Grails 3 中的 war 文件名 谢谢杰夫 我在 build gradle
  • 动态生成的 IL 中的值类型转换

    Update一年多后 我终于意识到了这种行为的原因 本质上 一个对象不能被拆箱为与它不同的类型 被装箱为 即使该类型强制转换或转换为目标 类型 如果你不知道正确的类型 你必须发现它 不知何故 作业可能完全有效 但不可行 让这一切自动发生 例
  • NUXT:使用 Markdown-it 显示相对于 Markdown 内容的图像

    这是 Nuxt 的纯静态实现 我正在使用从 yaml 内容文件 不是 markdown 读取的 markdown 内容 由于内容位于 json 对象中 因此它们正在使用 md render blog content 假设 blog cont
  • 改变正方形相交区域的颜色

    这些天我正在做一个项目 我的目标是改变两个正方形相交区域的颜色 我已经编写了检测两个正方形相交的代码 但我不知道如何更改相交区域的颜色 请帮我解决这个问题 var sketch function p with p let squares l
  • vue-cli-service 服务的依赖问题

    当我尝试构建 VueJS typescript 应用程序时 出现以下依赖项错误 vue cli service 服务 信息正在启动开发服务器 正在启动类型检查和 linting 服务 使用 1 个工作线程 内存限制为 2048MB 发出 C
  • 使 Jackson 在 JSON 中的重复属性上失败

    I use Jackson将 JSON 反序列化为不可变的自定义 Java 对象 这是课程 final class DataPoint private final int count private final int lower priv
  • 如果值是 `let` 常量,为什么我只能直接使用元组名称附加元组数组 - Swift

    这是我正在谈论的一个例子 typealias SomeTuple string String int Int var tupleArray SomeTuple Fails tupleArray append string Hello int