Swift 什么';基于结构和基于类的单例有什么区别?

Swift 什么';基于结构和基于类的单例有什么区别?,swift,Swift,这两种方法是否相同,或者是否存在需要注意的主要差异/陷阱: class MyClassSingleton { static let sharedInstance = MyClassSingleton() private init(){} func helloClass() { print("hello from class Singleton") } } struct MyStructSingleton { static let sharedInstance = MyStru

这两种方法是否相同,或者是否存在需要注意的主要差异/陷阱:

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") }
}

这取决于您想要实现什么,以及基于
class
struct
之间的差异,您想要如何使用您的结构。您将看到的最常见的事情是将类与单例对象一起使用

单例几乎是一样的,它们只创建一次,但是您将从
类和
结构中获得不同的行为,因为:

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

还有几个不同之处,但您可以从中了解到。

主要区别在于基于类的可变单例有效,而基于结构的可变“单例”无效。除非您想使您的单例不可变(这是很少见的),否则您应该坚持基于类的单例

下面是一个基于可变结构的“单例”如何不起作用的示例。考虑将可变成员<代码>状态< /代码>添加到这两个单体上,例如:

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)") }
}
我制作了
state
a
var
,但我可以将其公开为只读属性加上一个变异方法;关键是这两种类型现在都是可变的

如果我这样做

let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()
42被打印,因为
csi
正在引用共享实例

然而,当我对基于结构的singleton做同样的事情时

var ssi = MyStructSingleton.sharedInstance
ssi.state = 42
MyStructSingleton.sharedInstance.helloStruct()

5改为打印,因为
ssi
sharedInstance
的副本,这当然表明我们的单例实际上不是单例。

有趣的是,使用
static var sharedInstance
而不是
static let sharedInstance
使它看起来有效。是每次调用
MyStructSingleton.sharedInstance
?@RunningTurtle时生成的结构的新副本吗?声明类型为
MyStructSingleton
的新变量时,将创建
MyStructSingleton
的新副本。将
sharedInstance
指定给它后,这两个实例将变得相同,但它们不是相同的实例。当您将
MyStructSingleton
作为参数传递或从方法返回时,也会发生同样的情况。