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
}
}
I know superclass can solve the problem with super.init(...). But how to solve the problem without a superclass?
If your type remains non-public then you get that behaviour for free on structs, you can simply drop the entire init on S.
I know the default initializer would be provided, but it’s just kind of a trick. What if I’m gonna let every property plus one in init?
I don't understand this question.
I mean if I do this in my initializer:
init(...) {
self.a = a + 1
self.b = b + 1
...
}
I cannot rely on the default behavior.
Whether it is actually more concise depends on how many properties and types are involved, but the following strategy can be useful sometimes:
// The real public interface.
public protocol ManyProperties {
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)
}
// The internal shared implementation.
internal struct ManyPropertiesStorage {
let a: Int
let b: Int
let c: Int
let d: Int
}
internal protocol InternalManyProperties : ManyProperties {
init(storage: ManyPropertiesStorage)
var storage: ManyPropertiesStorage { get }
}
extension InternalManyProperties {
public var a: Int { return storage.a }
public var b: Int { return storage.b }
public var c: Int { return storage.c }
public var d: Int { return storage.d }
public init(a: Int, b: Int, c: Int, d: Int) {
self.init(storage: ManyPropertiesStorage(a: a + 1, b: b + 1, c: c + 1, d: d + 1))
}
}
// Short and sweet conformances.
public struct A: ManyProperties, InternalManyProperties {
internal let storage: ManyPropertiesStorage
}
public struct B: ManyProperties, InternalManyProperties {
internal let storage: ManyPropertiesStorage
}
public struct C: ManyProperties, InternalManyProperties {
internal let storage: ManyPropertiesStorage
}
public struct D: ManyProperties, InternalManyProperties {
internal let storage: ManyPropertiesStorage
}
CTMacUser
(Daryle Walker)
7
I don’t know what the “problem” actually is?
A property requirement can be satisfied with stored properties or computed ones. And your protocol doesn’t have an initializer requirement, and so doesn’t impose how you get the values in there to begin with.
This would be legal:
struct MyType: ManyProperties {
var a: Int { return Int.random(0..<10) }
var b: Int { return Int.random(0..<100) }
var c: Int { return Int.random(-10..<10) }
var d: Int { return Int.random(0..<1) }
}
So, can you explain more what the problem is?