Как избежать дублирования инициализации при принятии протокола? - PullRequest
0 голосов
/ 23 июня 2019

Я знаю, что могу сделать это с суперклассом, но Swift не поддерживает abstract class, и я хочу вместо этого использовать протокол.Однако, когда есть много требований к свойствам, мне очень трудно избежать дублирования self.xxx = xxx кода. Пример:

protocol ManyProperties {
    var a: Int { get }
    var b: Int { get }
    var c: Int { get }
    var d: Int { get }
}

struct S: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    // duplicate initializing
    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

Я действительно хочу напечатать что-то вроде super.init(), а я делаюне хочу наследства .Как мне это сделать?

1 Ответ

0 голосов
/ 24 июня 2019

Structs имеет бесплатный членный инициализатор, поэтому вам не нужно писать для них такой тип init:

struct S: ManyProperties {
    let a, b, c, d: Int
}

, но для класса у вас есть несколько вариантов:

1- Используйте базовый класс и наследуйте от него вместо того, чтобы соответствовать протоколу:

class ManyPropertiesClass: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    // duplicate initializing
    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyPropertiesClass {
}

2- Добавьте init в протокол, так что он заставит вас реализовать его с помощью небольшой подсказки по автозаполнению

protocol ManyProperties: class {
    var a: Int { get }
    var b: Int { get }
    var c: Int { get }
    var d: Int { get }

    init(a: Int, b: Int, c: Int, d: Int)}
}

3 - определить другой инициализатор внутри протокола и сделать переменные set способными, чтобы компилятор знал, что все свойства инициализированы.Затем вы можете расширить протокол для инициализации:

protocol ManyProperties: class {
    var a: Int { get set }
    var b: Int { get set }
    var c: Int { get set }
    var d: Int { get set }

    init()
}

extension ManyProperties {
    init(a: Int, b: Int, c: Int, d: Int) {
        self.init()
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyProperties {
    var a: Int = 0
    var b: Int = 0
    var c: Int = 0
    var d: Int = 0

    required init() {}
}
...