在Swift中,#file是否被认为是一个字面字符串?

问题描述 投票:5回答:1

漏洞 > 迅捷 > Enum > 字符串协议


我试图创建一个枚举,其中所有元素都是文件名,我偶然发现了一些有趣的东西。就像这样。

enum FileNames: String {
     case main = #file
}

这导致了一个内部错误: (Segmentation Fault: 11)


我是能够想办法得到一个实际的错误信息的。

enum Foo: String {
    case one = "\(1)"
}

Error: Raw value for enum case must be a literal


相关问题: - 是否 #file 被认为是一个字符串字面意思?- 为什么 #file 破坏枚举?是否应该在bug.swift.org上报告?- 我注意到,将 StringInt#file#line 导致同样的问题。这是一个提示吗?


颜色识字法不起作用

我以为是这样,但我犯了一个错误。它也会导致同样的内部错误。

import UIKit

enum ColorEnum: UIColor {
    case foo = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
}

Swift编程语言(Swift 5.2)。

根据苹果公司的。#file 被认为是一个字面意义。

#file is described as a literal according to Apple


那 "无 "字呢?

这些也会使编译器崩溃。

enum Foo: String? {
    case breaks = nil
}

23 大规模破坏的字符enum I:Int?{case a=nil}


错误修正

现在崩溃的问题已经修复,已经正式合并到Swift中。Merged on GitHub这是错误报告。SR-12998

增加支持 这里支持使用魔法字元作为枚举情况的原始值。SR-13022

swift enums literals
1个回答
2
投票

是的。#file#line文字表述 但你的程序还是不规范。

Swift语言参考 :

字符表达式由普通字符(如字符串或数字)、数组或字典字符、游戏场字符或下列特殊字符之一组成。

#file - String - 它出现的文件名。

#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

值得注意的是,只有 数形, 静态字符串, 布尔运算 是允许的。如果我们看一下他们的定义,很明显,这些。#因此,字面意思不符合 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

所有相关的规则,以完全定义 静态字符串 是长,但它仍然是小事一桩。静态字符串 推不出 #file 而不能包括插值。这就是它的静态化的原因)。

所以Swift编译器拒绝你的程序确实是正确的。不过,一个现代编译器不应该简单地在一个非法程序上崩溃,所以可能值得报告这个问题。


2
投票

这绝对是一个bug,所以值得向苹果提交反馈(虽然他们记录了那些#file、#function等是 特殊文字)

总之,以下的变通方法可能会对某些使用情况有所帮助。

enum FileNames {
    static let main = FileNames.file(#file)
    case file(String)
}
© www.soinside.com 2019 - 2024. All rights reserved.