基于Struct的单体和基于类的单体之间有什么区别?

Run*_*tle 36 swift

这两种方法是相同的还是存在重大差异/陷阱需要注意:

class MyClassSingleton {
  static let sharedInstance = MyClassSingleton()
  private init(){}

  func helloClass() { print("hello from class Singleton") }
}

struct MyStructSingleton {
  static let sharedInstance = MyStructSingleton()
  private init() {}

  func helloStruct() { print("hello from struct Singleton") }
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 70

主要区别在于基于类的可变单例工作,而基于结构的可变"单例"不工作.除非你想让你的单身人士不可变(这是罕见的)你应该坚持基于阶级的.

以下是基于可变结构的"单例"如何不起作用的说明.考虑向state两个单身人士添加一个可变成员,如下所示:

class MyClassSingleton {
    static let sharedInstance = MyClassSingleton()
    private init(){}
    var state = 5
    func helloClass() { print("hello from class Singleton: \(state)") }
}

struct MyStructSingleton {
    static let sharedInstance = MyStructSingleton()
    private init() {}
    var state = 5
    func helloStruct() { print("hello from struct Singleton: \(state)") }
}
Run Code Online (Sandbox Code Playgroud)

我做state了一个var,但我可以将它作为只读属性和一个变异方法公开; 重要的是这两种类型现在都是可变的.

如果我这样做

let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()
Run Code Online (Sandbox Code Playgroud)

42被打印,因为csi它引用了共享实例.

但是,当我使用基于结构的单例执行相同的操作时

var ssi = MyStructSingleton.sharedInstance
ssi.state = 42
MyStructSingleton.sharedInstance.helloStruct()
Run Code Online (Sandbox Code Playgroud)

相反,打印5,因为ssi是副本sharedInstance,这当然表明我们的单身实际上不是单身.

  • @RunningTurtle当您声明一个类型为"MyStructSingleton"的新变量时,会创建一个新的"MyStructSingleton"副本.一旦你为它分配了`sharedInstance`,两者就会变得相同,但它们不是同一个实例.将"MyStructSingleton"作为参数传递或从方法返回时,会发生同样的情况. (2认同)

Sai*_*ira 5

这取决于您希望实现的目标以及您希望如何根据class和之间的差异使用您的结构struct.您将看到的最常见的事情是使用带有singleton对象的类.

单身人士几乎是一样的,他们只创造一次,但你会得到不同的行为class,struct因为:

  • 类是引用类型,而结构是值类型
  • 结构用于定义简单结构
  • 结构不能被继承

还有一些差异,但你从中得到了这个想法.