可失败初始化器(init?)在Swift中允许描述创建类型实例可能失败并返回nil的情况。它们通常用于验证输入数据或可能不成功的转换。在可失败初始化器中,您可以显式返回nil,表示对象创建失败。
示例:
struct User { let name: String let age: Int init?(name: String, age: Int) { guard !name.isEmpty, age > 0 else { return nil } self.name = name self.age = age } }
因此,可以防止创建不正确的对象。
compactMap)时,这对于过滤无效实例很方便。问题: init?与init!有什么区别,以及何时使用带有隐式解包的可失败初始化器?
回答: init?返回一个可选类型(<type?>),如果初始化失败,将返回nil,这需要安全处理。init!返回一个隐式解包可选类型(<type!>),如果初始化失败,同样将返回nil,但在没有检查的情况下使用这样的对象将导致运行时崩溃。仅在您确定在您的上下文中初始化不可能失败时才使用init!(例如,在UIKit的storyboard中工作时)。
let value = Int("abc") // value将为nil
故事
在手动解析JSON时使用了常规初始化器而不是可失败初始化器。这导致创建了"空"用户,因为验证未能生效,应用程序未能过滤无效数据。
故事
使用
init!处理潜在的无效数据导致应用程序崩溃,在API更新后:输入数据格式发生变化,提取对象时出现运行时异常,因隐式解包nil。
故事
在自定义实现可失败初始化器时,忘记在某些场景下显式返回nil,最终结构初始化为"脏"字段,导致后续的业务逻辑错误。