如何避免子类中的默认初始化参数冗余?
How to avoid default init parameters redundancy in subclasses?
我想为某些初始化参数提供默认值。我希望能够在 subclasses 中重用相同的默认值,但找不到这样做的方法。
第一次尝试 - 参数默认值:
class A {
typealias Mapper = (A) -> String
let mapper: Mapper
init(mapper: Mapper = {a in "foo"}) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
init(myVar: Int, mapper: Mapper = {a in "foo"}) {
self.myVar = myVar
}
}
let b: B = B(myVar: 1)
let str = b.mapper(b)
let b2: B = B(myVar: 2, mapper: {a in "bar"})
我必须指定默认值两次(在 A 和 B init 中)才能使用或不使用默认值初始化 B。
我也试过使用便利初始化器,同样的问题:
class A {
typealias Mapper = (A) -> String
let mapper: Mapper
convenience init() {
self.init(mapper: {a in "foo"})
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: {a in "foo"})
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
我想也许至少我把默认值放在一个静态变量中,像这样:
class A {
typealias Mapper = (A) -> String
static let defMapper: Mapper = {a in "foo"}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper)
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper)
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
(也可以将变量定义为惰性变量,以避免在不使用默认参数时进行初始化)
在我将泛型类型添加到 A 之前一直有效。然后我得到 "static properties not yet supported in generic types"。所以我必须将默认值放在 class 之外,这导致还必须将类型别名定义放在 class 之外,如果我将泛型添加到混合中,这将是一团糟。
有办法解决吗?
如何使用计算 属性:
class A<T> {
typealias Mapper = (A) -> String
static var defMapper: Mapper {
return { a in "foo" }
}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper)
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B<T>: A<T> {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper)
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
let b: B = B<String>(myVar: 1)
let str = b.mapper(b)
let b2: B = B<String>(myVar: 2, mapper: {a in "bar"})
A<Int>(mapper: {a in "bar"})
A<Int>()
或类型方法:
class A<T> {
typealias Mapper = (A) -> String
static func defMapper() -> Mapper {
return { a in "foo" }
}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper())
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B<T>: A<T> {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper())
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
let b: B = B<String>(myVar: 1)
let str = b.mapper(b)
let b2: B = B<String>(myVar: 2, mapper: {a in "bar"})
A<Int>(mapper: {a in "bar"})
A<Int>()
我想为某些初始化参数提供默认值。我希望能够在 subclasses 中重用相同的默认值,但找不到这样做的方法。
第一次尝试 - 参数默认值:
class A {
typealias Mapper = (A) -> String
let mapper: Mapper
init(mapper: Mapper = {a in "foo"}) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
init(myVar: Int, mapper: Mapper = {a in "foo"}) {
self.myVar = myVar
}
}
let b: B = B(myVar: 1)
let str = b.mapper(b)
let b2: B = B(myVar: 2, mapper: {a in "bar"})
我必须指定默认值两次(在 A 和 B init 中)才能使用或不使用默认值初始化 B。
我也试过使用便利初始化器,同样的问题:
class A {
typealias Mapper = (A) -> String
let mapper: Mapper
convenience init() {
self.init(mapper: {a in "foo"})
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: {a in "foo"})
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
我想也许至少我把默认值放在一个静态变量中,像这样:
class A {
typealias Mapper = (A) -> String
static let defMapper: Mapper = {a in "foo"}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper)
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B: A {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper)
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
(也可以将变量定义为惰性变量,以避免在不使用默认参数时进行初始化)
在我将泛型类型添加到 A 之前一直有效。然后我得到 "static properties not yet supported in generic types"。所以我必须将默认值放在 class 之外,这导致还必须将类型别名定义放在 class 之外,如果我将泛型添加到混合中,这将是一团糟。
有办法解决吗?
如何使用计算 属性:
class A<T> {
typealias Mapper = (A) -> String
static var defMapper: Mapper {
return { a in "foo" }
}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper)
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B<T>: A<T> {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper)
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
let b: B = B<String>(myVar: 1)
let str = b.mapper(b)
let b2: B = B<String>(myVar: 2, mapper: {a in "bar"})
A<Int>(mapper: {a in "bar"})
A<Int>()
或类型方法:
class A<T> {
typealias Mapper = (A) -> String
static func defMapper() -> Mapper {
return { a in "foo" }
}
let mapper: Mapper
convenience init() {
self.init(mapper: A.defMapper())
}
init(mapper: Mapper) {
self.mapper = mapper
}
}
class B<T>: A<T> {
let myVar: Int
convenience init(myVar: Int) {
self.init(myVar: myVar, mapper: A.defMapper())
}
init(myVar: Int, mapper: Mapper) {
self.myVar = myVar
super.init(mapper: mapper)
}
}
let b: B = B<String>(myVar: 1)
let str = b.mapper(b)
let b2: B = B<String>(myVar: 2, mapper: {a in "bar"})
A<Int>(mapper: {a in "bar"})
A<Int>()