泛型类不调用重写初始化器

时间:2022-10-29 16:04:55
class Gen<T: A> {
    func create() -> T {
        if T.self is B.Type {
            println("YES")
        }
        return T(id: "cool")
    }
}

class A {
    let id: String

    init(id: String) {
        self.id = id
        println("class A \(id)")
    }
}

class B: A {
    override init(id: String) {
        println("class B \(id)")
        super.init(id: id)
    }
}

let coll = Gen<B>()
let t = coll.create()

output is "YES" "class A cool"

输出是“YES”“class A cool”

There is no output from overridden B.init.

没有被重写的B.init的输出。

Is that a compiler bug? Do I need to do it differently?

这是编译错误吗?我需要做不同的事情吗?

Xcode 6.1

Xcode 6.1

2 个解决方案

#1


2  

That looks like a compiler bug.

这看起来像一个编译器错误。

If you try:

如果你尝试:

NSStringFromClass(t.dynamicType)

it (playground) outputs something like:

它(操场)输出如下:

__lldb_expr_781.A

__lldb_expr_781.A

so t is of type A. More interestingly:

t属于a型,更有趣的是

let t: B = coll.create()

doesn't generate any compilation error, but it's a huge compilation mistake, because if the instance is of type A, it cannot be assigned to a variable of type B (because B is a subclass of A, but the opposite is possible thanks to polymorphism).

不会产生任何编译错误,但是这是一个巨大的编译错误,因为如果实例是a类型的,那么它就不能分配给B类型的变量(因为B是a的一个子类,但是由于多态性,可能会出现相反的情况)。

To prove that: add any property to the B class, like:

证明:向B类添加任何属性,如:

var x = 0

if you try accessing it:

如果您尝试访问它:

t.x

a runtime error is reported (EXC_BAD_ACCESS).

报告运行时错误(EXC_BAD_ACCESS)。

Also read this Q/A, it's a similar problem (if not the same)

也读一下这个Q/A,这是一个类似的问题(如果不是一样的话)

#2


0  

You need to make initializers required, then add let realType = T.self line to create() method and replace T() with realType().

您需要使初始化器成为必需的,然后添加let realType = T。创建()方法并将T()替换为realType()。

class Gen<T: A> {
    func create() -> T {
        let realType = T.self
        return realType(id: "cool")
    }
}

class A {
    let id: String

    required init(id: String) {
        self.id = id
        println("class A \(id)")
    }
}

class B: A {
    required init(id: String) {
        println("class B \(id)")
        super.init(id: id)
    }
}

let coll = Gen<B>()
let t = coll.create()

#1


2  

That looks like a compiler bug.

这看起来像一个编译器错误。

If you try:

如果你尝试:

NSStringFromClass(t.dynamicType)

it (playground) outputs something like:

它(操场)输出如下:

__lldb_expr_781.A

__lldb_expr_781.A

so t is of type A. More interestingly:

t属于a型,更有趣的是

let t: B = coll.create()

doesn't generate any compilation error, but it's a huge compilation mistake, because if the instance is of type A, it cannot be assigned to a variable of type B (because B is a subclass of A, but the opposite is possible thanks to polymorphism).

不会产生任何编译错误,但是这是一个巨大的编译错误,因为如果实例是a类型的,那么它就不能分配给B类型的变量(因为B是a的一个子类,但是由于多态性,可能会出现相反的情况)。

To prove that: add any property to the B class, like:

证明:向B类添加任何属性,如:

var x = 0

if you try accessing it:

如果您尝试访问它:

t.x

a runtime error is reported (EXC_BAD_ACCESS).

报告运行时错误(EXC_BAD_ACCESS)。

Also read this Q/A, it's a similar problem (if not the same)

也读一下这个Q/A,这是一个类似的问题(如果不是一样的话)

#2


0  

You need to make initializers required, then add let realType = T.self line to create() method and replace T() with realType().

您需要使初始化器成为必需的,然后添加let realType = T。创建()方法并将T()替换为realType()。

class Gen<T: A> {
    func create() -> T {
        let realType = T.self
        return realType(id: "cool")
    }
}

class A {
    let id: String

    required init(id: String) {
        self.id = id
        println("class A \(id)")
    }
}

class B: A {
    required init(id: String) {
        println("class B \(id)")
        super.init(id: id)
    }
}

let coll = Gen<B>()
let t = coll.create()