DateFormatter遵循ExpressibleByStringLiteral协议报错如何解决?
问题分析
你遇到的报错如下:
Initializer requirement 'init(stringLiteral:)' can only be satisfied by a 'required' initializer in the definition of non-final class 'DateFormatter'
你的原有实现为在扩展中给DateFormatter添加协议遵循的便利初始化器:
extension DateFormatter: ExpressibleByStringLiteral { public convenience init(stringLiteral value: String) { self.init() self.dateFormat = value } }
报错原因
DateFormatter是非final类,允许被继承。对于非final类,要满足协议的初始化器要求,必须将对应初始化器标记为required,确保所有子类都能实现该初始化器,符合协议约束- Swift语法规定
required初始化器只能定义在类的主声明中,不能定义在扩展里。你无法修改苹果官方DateFormatter的源码,因此无法直接通过扩展让DateFormatter遵循ExpressibleByStringLiteral协议。
可行解决方案
方案1:继承DateFormatter实现final子类
final类无法被继承,不需要required约束即可满足协议要求,实现代码如下:
final class StringLiteralDateFormatter: DateFormatter, ExpressibleByStringLiteral { init(stringLiteral value: String) { super.init() dateFormat = value } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // 使用示例 let dateFormatter: StringLiteralDateFormatter = "yyyy-MM-dd HH:mm:ss"
方案2:使用结构体包装DateFormatter
如果不想引入子类,也可以用结构体做一层轻量包装实现协议:
struct FormatterWrapper: ExpressibleByStringLiteral { let formatter: DateFormatter init(stringLiteral value: String) { let formatter = DateFormatter() formatter.dateFormat = value self.formatter = formatter } } // 使用示例 let wrapper: FormatterWrapper = "yyyy-MM-dd" let date = wrapper.formatter.date(from: "2024-01-01")
内容的提问来源于stack exchange,提问作者Kaunteya
相关产品推荐
相关产品推荐

