Swift中类能否像结构体一样使用默认成员初始化?
Swift 类默认成员初始化能力说明
截止当前最新正式发布的Swift 5.x版本,类(class)依然没有提供和结构体(struct)一致的自动逐成员初始化能力,你在示例中遇到的类传参初始化报错问题,在当前版本仍然存在。
两类类型的自动初始化规则差异
- 结构体的自动初始化规则:
只要没有手动实现所有构造方法,编译器会自动生成两类构造器:一是全属性使用默认值的无参构造器,二是覆盖所有存储属性的逐成员构造器。调用逐成员构造器时,你可以按需省略已经设置了默认值的属性参数,编译器会自动补用预设默认值,这也是示例里FooStruct(id: UUID())、FooStruct(title: "bar")可以正常运行的原因。 - 类的自动初始化规则:
编译器对类的自动构造器生成限制非常严格:仅当类的所有存储属性都设置了默认初始值、且开发者没有手动编写任何自定义构造方法时,才会自动生成一个无参数的默认构造器,永远不会自动生成带成员参数的逐成员构造器。如果需要传入成员参数完成类实例初始化,必须手动声明对应的init方法。
规则验证代码
import Foundation struct FooStruct { var id: UUID = UUID() var title = "" } // 结构体调用合法 let a = FooStruct(id: UUID()) let a2 = FooStruct(title: "bar") class FooClass { var id: UUID = UUID() var title = "" } // 类调用会抛出错误:Argument passed to call that takes no arguments let b = FooClass(id: UUID()) let b2 = FooClass(title: "bar")
类实现同等灵活初始化的方案
如果想让类支持和结构体一样的任意组合传参初始化,只需要手动编写全参构造器,给每个参数设置和属性默认值一致的默认参数即可,参考实现:
class FooClass { var id: UUID var title: String init(id: UUID = UUID(), title: String = "") { self.id = id self.title = title } } // 实现后以下所有调用均合法 let b = FooClass(id: UUID()) let b2 = FooClass(title: "bar") let b3 = FooClass() let b4 = FooClass(id: UUID(), title: "bar")
内容的提问来源于stack exchange,提问作者Kem Mason
相关产品推荐
相关产品推荐

