如何避免子类中的默认init参数冗余?

时间:2015-05-06 10:13:26

标签: swift generics default-value

我想为某些初始化参数提供默认值。我希望能够在子类中重用相同的默认值,但却找不到这样做的方法。

首先尝试 - 参数默认值:

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添加泛型类型。然后我得到“泛型类型尚不支持的静态属性”。因此我必须将默认值放在类之外,这导致也必须将类型别定义放在类之外,如果我在混合中添加泛型,那就非常混乱了。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:2)

如何使用计算属性:

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>()