Какая разница между синглтонами на основе Struct и Class?

Являются ли эти два подхода одинаковыми или существуют существенные различия/ловушки, о которых следует знать:

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

Ответ 1

Основное отличие заключается в том, что работает многопользовательский однопользовательский режим, в то время как структурный изменчивый "singleton" - нет. Если вы не хотите сделать свой синглтон неизменным (что редко), вы должны придерживаться класса.

Вот иллюстрация того, как изменчивый структурный "singleton" не работает. Подумайте о добавлении изменяемого члена 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)") }
}

Я сделал state a var, но я мог бы представить его как свойство только для чтения плюс мутирующий метод; главное, что оба типа теперь изменяемы.

Если я сделаю это

let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()

42 печатается, потому что csi ссылается на общий экземпляр.

Однако, когда я делаю то же самое со структурным синглоном

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

5 вместо этого печатается, потому что ssi является копией sharedInstance, что, конечно же, указывает на то, что наш синглтон на самом деле не является одиночным.

Ответ 2

Это зависит от того, чего вы хотите достичь и как вы хотите использовать свою структуру на основе различий между class и struct. Наиболее распространенная вещь, которую вы увидите, - это использование класса с одиночным объектом.

Синглтоны практически одинаковы, они создаются только один раз, но вы получите разные типы поведения от class и от struct, потому что:

  • Классы - это ссылочные типы, а структуры - типы значений
  • Структуры используются для определения простых структур
  • Структуры не могут быть унаследованы

Есть еще несколько отличий, но вы получите эту идею.