您可以 return 来自 Swift 构造函数的不同实例吗?

Can you return a different instance from a Swift constructor?

Objective-C 有一种特殊但非常有用的能力,可以使初始化程序 return 成为与调用初始化程序的实例不同的实例。你可以阅读 here.

它非常适合 class 集群之类的东西,但即使是像确保特定实例根据特定条件 returned 这样简单的事情(即用 class 新建一个帐户一个帐号将始终 return 与该号码的帐户 class 相同的实例。)

但是,在我们的应用程序中,我们使用的是 Swift,但我没有在这种语言中看到任何此类规定。有这种东西吗?

通常我们会简单地为 return 我们感兴趣的实例创建一个 class 方法,但是虽然我们拥有所讨论的 class,但我们不拥有使用标准初始化语法的调用代码。例如

let foo = OurClass()

我们想根据一些外部条件来控制将哪个实例交还给他们(为清楚起见,此处省略。)

那么Swift有这样的机制吗?

虽然不像 objective-c 那样简单或干净,但希望您应该能够使用 便利初始化器 可失败初始化器 (或两者)。

便捷初始化器允许您将初始化委托给另一个初始化器,实质上让您控制对象的初始化方式:

  class RecipeIngredient {
    var quantity: Int

    init(quantity: Int) {
        self.quantity = quantity
    }
    convenience init() {
        // You control how the properties are initialized here
        if (/* Some external or internal condition */) {
           self.init(quantity: 1)
        }
        else {
           self.init(quantity: 2)
        }
    }
 }

 // The caller
 let mysteryFood = Food()

如果不满足条件或在初始化期间发生错误,可失败初始化程序允许您在指定的初始化程序中 return nil:

class Account {
    var id: Int

    // Failable initializers have '?' after init
    init?(id: Int) {
        // You control if the initialization succeeds or not
        if (/* check your db if id is duplicate, for example */) {
          return nil
        }
        // Succeeds
        self.quantity = quantity
    }
 }

 // The caller
 let account = Account(id: 5)
 if (account == nil) { 
   // It failed 
 }
 else { 
   // It succeeded 
 }

在您的情况下,根据您的评论,听起来您想使用 可失败的初始化程序 如果调用者试图创建 returns nil一个重复的实例。

希望这符合您的要求!

据我所知,使用 classes 是不可能的,但是您可以使用结构初始值设定项 (self = otherValue) 来做到这一点。如果可能的话, class 可以转换成一个结构,这可能是可行的方法。

明显的替代方案(并且可以说是更好的设计)是工厂方法,当使用已经存在的 API 时,您可以弃用该初始化程序或使其容易出错以指示应改为使用工厂方法.否则,我会想到几个选项。

  1. 将您想要 return 的实例的属性复制到您正在创建的新实例。
  2. 按照建议,下拉到 Objective-C,作为初始值设定项。
  3. 仅对 Swift 使用子class 并强制使用构造函数。