swift - #file 是否被视为 Swift 中的文字字符串?
问题描述
错误> Swift >枚举>字符串协议
我试图创建一个枚举,其中所有元素都是文件名,我偶然发现了一些有趣的东西。像这样:
enum FileNames: String {
case main = #file
}
这导致了内部错误。(分段错误:11)
我能够弄清楚如何获得实际的错误消息:
enum Foo: String {
case one = "\(1)"
}
Error: Raw value for enum case must be a literal
相关问题:
• 是否#file
被视为字符串文字?
• 为什么要#file
破坏枚举?这应该在 bugs.swift.org 上报告吗?
• 我注意到替换String
toInt
和#file
to#line
会导致同样的问题。这是提示吗?
颜色文字不起作用
我以为他们做到了,但我犯了一个错误。它也会导致相同的内部错误。
import UIKit
enum ColorEnum: UIColor {
case foo = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
}
Swift 编程语言 (Swift 5.2)
根据 Apple 的说法,#file
被认为是文字:
那么 nil 字面量呢?
这些也会使编译器崩溃。
enum Foo: String? {
case breaks = nil
}
23个大规模毁灭性人物
enum I:Int?{case a=nil}
错误修复
崩溃现已修复,它已在此处正式合并到 Swift:Merged on GitHub 这是错误报告:SR-12998。它已在 Swift 5.4 中正式实现
添加支持!
这里支持使用魔法文字作为枚举案例的原始值:SR-13022
解决方案
是的,#file
并且#line
是文字表达式,但您的程序仍然格式错误。
Swift 语言参考说:
文字表达式由普通文字(如字符串或数字)、数组或字典文字、游乐场文字或以下特殊文字之一组成:
#file
— 字符串 — 出现的文件的名称。
#line
— Int — 它出现的行号。[...]
我们还要注意语法:
literal-expression → literal
literal-expression → array-literal | dictionary-literal | playground-literal
literal-expression → #file | #line | #column | #function | #dsohandle
现在让我们考虑您正在定义的枚举的语法。我在这里只包括最相关的部分,您可以自己验证完整的推论:
enum-declaration → attributes opt access-level-modifier opt raw-value-style-enum
[...]
raw-value-style-enum → enum enum-name generic-parameter-clause opt type-inheritance-clause generic-where-clause opt { raw-value-style-enum-members }
[...]
raw-value-assignment → = raw-value-literal
raw-value-literal → numeric-literal | static-string-literal | boolean-literal
值得注意的是,只允许numeric-literal、static-string-literal、boolean-literal。如果我们查看它们的定义,很明显这些#
文字不符合raw-value-literal
规则:
numeric-literal → -opt integer-literal | -opt floating-point-literal
boolean-literal → true | false
static-string-literal → string-literal-opening-delimiter quoted-text opt string-literal-closing-delimiter
static-string-literal → multiline-string-literal-opening-delimiter multiline-quoted-text opt multiline-string-literal-closing-delimiter
完全定义static-string-literal的所有相关规则都很长,但是看到static-string-literal不能被推导#file
并且不能包含插值仍然是微不足道的。(这就是使它成为静态的原因。)
所以 Swift 编译器拒绝你的程序确实是正确的。尽管如此,现代编译器不应该简单地在非法程序上崩溃,因此可能值得报告这个问题。
推荐阅读
- stm32 - 无法闪烁 JTDI 引脚
- c# - 如何将方法发送到 asp.net 核心中的 Rabbitmq 队列
- fiware - Perseo Docker Build 上的安装超时
- java - 用新文本替换 PDF 文本
- javascript - 使用带有 tensorflow js 的图形文件(.pb 文件)进行预测
- ms-access - MSysobjects 表中“标志”字段值的定义是什么
- database-migration - 将 dbms_crypto 加密数据从 oracle 迁移到 PostgreSQL
- asp.net - 当 System.IO.FileStream 导致访问冲突错误时,为什么 File.ReadAllBytes 在 IIS 服务器上工作
- java - 如何通过Java获取MySQL表中一列不同值的ID?
- ios - Swift 4.1 JWT http 标头承载在服务器中返回 401