你能从Swift构造函数返回一个不同的实例吗?

时间:2016-11-28 21:14:43

标签: swift initializer

Objective-C具有一种特殊但非常有用的能力,可以使初始化程序返回与调用初始化程序的实例不同的实例。您可以阅读here

对于类集群这样的事情来说非常棒,但即使对于确保根据特定条件返回特定实例这样简单的事情(例如,使用帐号创建一个Account类总是会返回相同的Account类实例)数。)

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

通常我们只是创建一个类方法来返回我们感兴趣的实例,但是当我们拥有相关的类时,我们不拥有使用标准初始化语法的调用代码。 e.g。

let foo = OurClass()

我们希望根据一些外部条件控制将哪个实例传回给他们(为清楚起见,这里省略了。)

Swift也有这样的机制吗?

2 个答案:

答案 0 :(得分:0)

虽然不像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()

如果条件不满足或初始化期间发生错误,则可用的初始化程序允许您在指定的初始化程序中返回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 
 }

在您的情况下,根据您的评论,听起来您希望使用可用的初始化程序,如果调用者尝试创建重复的实例,则返回nil。

希望这与您所寻找的一致!

答案 1 :(得分:0)

据我所知,类不可能,但您可以使用struct initializers(self = otherValue)来完成此操作。如果可能的话,可以将类转换为可能是可行的结构。

明显的替代方案(可以说是更好的设计)是一种工厂方法,当使用现有的API时,您可以弃用该初始化程序或使其易于指示应该使用工厂方法。否则会有一些选项浮现在脑海中。

  1. 将要返回的实例的属性复制到您正在创建的新实例中。
  2. 按照建议,下拉到Objective-C,用于初始化程序。
  3. 仅为Swift使用子类并强制使用构造函数。