【问题标题】:Is using nested initializers in Swift bad practice?在 Swift 中使用嵌套初始化器是不好的做法吗?
【发布时间】:2016-06-17 19:48:13
【问题描述】:

假设我有这样的 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
}

哪种做法更好,甚至会有所作为?

【问题讨论】:

    标签: ios swift properties initialization swift3


    【解决方案1】:

    实际上你只需要一个初始化器。

    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 中的一个东西。
    【解决方案2】:

    这是不正确的。基于 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2019-02-12
      相关资源
      最近更新 更多