在 Swift 中使用嵌套初始化器是不好的做法吗?
Is using nested initializers in Swift bad practice?
假设我有这样的 Swift struct
设置:
struct User {
// Properties
var name: String?
var username: String!
var email: String?
}
现在,在我看来,有两种设计初始化程序的方法。
这是第一个:
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.username = username
self.name = name
}
init(username: String, name: String, email: String) {
self.username = username
self.name = name
self.email = email
}
这是第二个:
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.init(username: username)
self.name = name
}
init(username: String, name: String, email: String) {
self.init(username: username, name: name)
self.email = email
}
哪种做法更好,甚至有什么不同吗?
这是不正确的。根据 Apple 文档,如果您想制作多个执行相同操作的初始化程序,您可以使用这样的便利初始化程序。便利初始化器最终会调用指定的初始化器。
convenience init(username: String?) {
self.init(username: username, name: nil)
}
convenience init(username: String?, name: String?) {
self.init(username: username, name: name, email: nil)
}
// designated initializer
init(username: String?, name: String?, email: String?) {
self.init(username: username, name: name)
self.email = email
}
现在你可以这样称呼它了
let user = User(username: "john")
或
let user = User(username: "john", name: "John Doe")
或
let user = User(username: "john", name: "John Doe", email: "johndoe@domain.com")
实际上你只需要一个初始化程序。
username
好像是必须的,所以声明为非可选的。
如果您为其他参数提供默认值,则可以省略它们。
struct User {
// Properties
var name: String?
var username : String
var email: String?
init(username: String, name: String? = nil, email: String? = nil) {
self.username = username
self.name = name
self.email = email
}
}
现在你可以通过一个初始化器使用这三种形式
User(username: "Foo")
User(username: "Foo", name: "Bar")
User(username: "Foo", name: "Bar", email:"john@doe.com")
在这种情况下,我建议将所有属性声明为非可选属性。值的缺失可以用空字符串表示,您永远不必处理可选绑定或强制解包。
struct User {
// Properties
var name, username, email : String
init(username: String, name: String = "", email: String = "") {
...
初始化器的行为完全相同
假设我有这样的 Swift struct
设置:
struct User {
// Properties
var name: String?
var username: String!
var email: String?
}
现在,在我看来,有两种设计初始化程序的方法。
这是第一个:
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.username = username
self.name = name
}
init(username: String, name: String, email: String) {
self.username = username
self.name = name
self.email = email
}
这是第二个:
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.init(username: username)
self.name = name
}
init(username: String, name: String, email: String) {
self.init(username: username, name: name)
self.email = email
}
哪种做法更好,甚至有什么不同吗?
这是不正确的。根据 Apple 文档,如果您想制作多个执行相同操作的初始化程序,您可以使用这样的便利初始化程序。便利初始化器最终会调用指定的初始化器。
convenience init(username: String?) {
self.init(username: username, name: nil)
}
convenience init(username: String?, name: String?) {
self.init(username: username, name: name, email: nil)
}
// designated initializer
init(username: String?, name: String?, email: String?) {
self.init(username: username, name: name)
self.email = email
}
现在你可以这样称呼它了
let user = User(username: "john")
或
let user = User(username: "john", name: "John Doe")
或
let user = User(username: "john", name: "John Doe", email: "johndoe@domain.com")
实际上你只需要一个初始化程序。
username
好像是必须的,所以声明为非可选的。
如果您为其他参数提供默认值,则可以省略它们。
struct User {
// Properties
var name: String?
var username : String
var email: String?
init(username: String, name: String? = nil, email: String? = nil) {
self.username = username
self.name = name
self.email = email
}
}
现在你可以通过一个初始化器使用这三种形式
User(username: "Foo")
User(username: "Foo", name: "Bar")
User(username: "Foo", name: "Bar", email:"john@doe.com")
在这种情况下,我建议将所有属性声明为非可选属性。值的缺失可以用空字符串表示,您永远不必处理可选绑定或强制解包。
struct User {
// Properties
var name, username, email : String
init(username: String, name: String = "", email: String = "") {
...
初始化器的行为完全相同