#file 是否被视为 Swift 中的文字字符串?
Is #file considered a literal String in 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
替换为Int
并将#file
替换为#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。 Swift5.4
正式实现
添加支持!
此处支持使用魔术文字作为枚举案例的原始值:SR-13022
这绝对是一个错误,因此值得向 Apple 提交反馈(尽管他们记录了那些#file、#function 等是特殊文字)
无论如何,以下解决方法可能对某些用例有用:
enum FileNames {
static let main = FileNames.file(#file)
case file(String)
}
是的,#file
和 #line
是 文字表达式 但是你的程序仍然是错误的。
Swift语言参考says:
A literal expression consists of either an ordinary literal (such as a string or a number), an array or dictionary literal, a playground literal, or one of the following special literals:
#file
— String — The name of the file in which it appears.
#line
— Int — The line number on which it appears.
[...]
我们也注意一下语法:
literal-expression → literal
literal-expression → array-literal | dictionary-literal | playground-literal
literal-expression → #file | #line | #column | #function | #dsohandle
现在让我们考虑一下您正在定义的 grammar of the enum。我在这里只包括最相关的部分你可以自己验证完整的推论:
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[=43=仍然很简单] 不能推断为 #file
并且不能包括插值。 (这就是它静态的原因。)
所以Swift编译器拒绝你的程序确实是对的。尽管如此,现代编译器不应该简单地在非法程序上崩溃,因此可能值得报告这个问题。
Swift 5.4 修复了崩溃问题
Swift 5.4 实现了 SR-12998
的错误修复
编译器不再崩溃,而是显示描述性错误消息:
来自字符串的魔法文字
enum Foo: String {
// Compiler Error: Use of '#file' literal as raw value for enum case is not supported
case b = #file
// Compiler Error: Use of '#function' literal as raw value for enum case is not supported
case c = #function
}
来自整数的魔法文字
enum B: Int {
// Compiler Error: Use of '#line' literal as raw value for enum case is not supported
case b = #line
// Compiler Error: Use of '#column' literal as raw value for enum case is not supported
case c = #column
}
来自 UnsafeRawPointers 的魔法文字
extension UnsafeRawPointer: ExpressibleByIntegerLiteral {}
enum Wo: UnsafeRawPointer {
// Compiler Error: Use of '#dsohandle' literal as raw value for enum case is not supported
case wo = #dsohandle
}
以这种方式使用 Magic Literal nil
现在会显示不同的错误,而不是使编译器崩溃。
enum Foo: String? {
case breaks = nil
}
enum I:Int?{case a=nil}
还没有完全修复:
然而,魔术文字 nil
仍然会导致编译器崩溃:
extension Optional: ExpressibleByIntegerLiteral where Wrapped == Int {}
enum Foo: Int? {
// Compiler Crashes: Segmentation fault: 11
case c = nil
}
此外,UIColor 的魔法字面值仍然会导致编译器崩溃:
import UIKit
extension UIColor: ExpressibleByIntegerLiteral {}
enum ColorEnum: UIColor {
// Compiler Crashes: Segmentation fault: 11
case foo = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
}
错误 > 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
替换为Int
并将#file
替换为#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。 Swift5.4
正式实现添加支持!
此处支持使用魔术文字作为枚举案例的原始值:SR-13022
这绝对是一个错误,因此值得向 Apple 提交反馈(尽管他们记录了那些#file、#function 等是特殊文字)
无论如何,以下解决方法可能对某些用例有用:
enum FileNames {
static let main = FileNames.file(#file)
case file(String)
}
是的,#file
和 #line
是 文字表达式 但是你的程序仍然是错误的。
Swift语言参考says:
A literal expression consists of either an ordinary literal (such as a string or a number), an array or dictionary literal, a playground literal, or one of the following special literals:
#file
— String — The name of the file in which it appears.
#line
— Int — The line number on which it appears.[...]
我们也注意一下语法:
literal-expression → literal
literal-expression → array-literal | dictionary-literal | playground-literal
literal-expression → #file | #line | #column | #function | #dsohandle
现在让我们考虑一下您正在定义的 grammar of the enum。我在这里只包括最相关的部分你可以自己验证完整的推论:
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[=43=仍然很简单] 不能推断为 #file
并且不能包括插值。 (这就是它静态的原因。)
所以Swift编译器拒绝你的程序确实是对的。尽管如此,现代编译器不应该简单地在非法程序上崩溃,因此可能值得报告这个问题。
Swift 5.4 修复了崩溃问题
Swift 5.4 实现了 SR-12998
的错误修复编译器不再崩溃,而是显示描述性错误消息:
来自字符串的魔法文字
enum Foo: String {
// Compiler Error: Use of '#file' literal as raw value for enum case is not supported
case b = #file
// Compiler Error: Use of '#function' literal as raw value for enum case is not supported
case c = #function
}
来自整数的魔法文字
enum B: Int {
// Compiler Error: Use of '#line' literal as raw value for enum case is not supported
case b = #line
// Compiler Error: Use of '#column' literal as raw value for enum case is not supported
case c = #column
}
来自 UnsafeRawPointers 的魔法文字
extension UnsafeRawPointer: ExpressibleByIntegerLiteral {}
enum Wo: UnsafeRawPointer {
// Compiler Error: Use of '#dsohandle' literal as raw value for enum case is not supported
case wo = #dsohandle
}
以这种方式使用 Magic Literal nil
现在会显示不同的错误,而不是使编译器崩溃。
enum Foo: String? {
case breaks = nil
}
enum I:Int?{case a=nil}
还没有完全修复:
然而,魔术文字 nil
仍然会导致编译器崩溃:
extension Optional: ExpressibleByIntegerLiteral where Wrapped == Int {}
enum Foo: Int? {
// Compiler Crashes: Segmentation fault: 11
case c = nil
}
此外,UIColor 的魔法字面值仍然会导致编译器崩溃:
import UIKit
extension UIColor: ExpressibleByIntegerLiteral {}
enum ColorEnum: UIColor {
// Compiler Crashes: Segmentation fault: 11
case foo = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
}