【问题标题】:ExpressibleByStringLiteral with optionals in function parametersExpressibleByStringLiteral 在函数参数中带有选项
【发布时间】:2020-08-05 13:05:32
【问题描述】:

考虑以下枚举

enum Text: Equatable {
    case plain(String)
    case attributed(NSAttributedString)
}

我已经使它符合ExpressibleByStringLiteral

extension Text: ExpressibleByStringLiteral {
    public typealias StringLiteralType = String
    
    public init(stringLiteral value: StringLiteralType) {
        self = .plain(value)
    }
}

有了这一切,我可以像我期望的那样做以下事情:

let text: Text = "Hello" // .plain("Hello")
let text2: Text? = "Hello" // .plain("Hello")

但我得到以下编译器错误:

let nilString: String? = nil
let text3: Text? = nilString // Cannot convert value of type 'String?' to expected argument type 'Text?'

func foo(text: Text?) { /** foo **/ }
let text = "Hello"
foo(text: text) // Cannot convert value of type 'String' to expected argument type 'Text?'

func bar(text: Text?) { /** bar **/ }
bar(text: nilString) // Cannot convert value of type 'String?' to expected argument type 'Text?'

我怎样才能让这些工作?

我也尝试过扩展 Optional: ExpressibleByStringLiteral where Wrapped: ExpressibleByStringLiteral,但这没有帮助。

【问题讨论】:

  • 展示你的 foo 和 bar 实现。为什么在使用字符串字面量初始化对象时声明对象是可选的?
  • @LeoDabus 为了这个例子。在实际代码中,我使用接受String? 的函数并调用其他需要Text? 的函数。 foobar 都没有实现,因为单独的代码会引发编译器错误
  • 只处理你的选项。检查它的可选性并打开它有什么问题?
  • Resuming “StringLiteralType 的有效类型是 String 和 StaticString。” 如果您想在初始化 Text 时处理可选字符串,只需为此创建一个可出错的初始化程序。 init?(_ string: String?) { guard let string = string else { return nil } self = .plain(string) } 然后let text3 = Text(nilString)
  • nilString.map(Text.plain)

标签: swift string optional


【解决方案1】:

ExpressibleByStringLiteral 不是关于将(String, Int) 自动转换为您的自定义类型。字面量正好是"word"字符串字面量)或12.63双字面量)。 但在您的示例中,let text = "Hello" 常量文本的类型为 String。但是方法 foo 期望输入 Text? 作为参数。

但你可以像这样使用它

foo(text: "Some text")

现在编译器知道它可以将您的字符串文字转换为文本。然后将其包装成Optional<Text>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-28
    • 2011-04-28
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2017-03-28
    相关资源
    最近更新 更多