作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
考虑以下 Playground :
import Foundation
protocol StringInitable {
init( string:String )
}
class A : StringInitable {
var stored:String
required init ( string:String ) {
stored = string
}
}
class B : A /*, StringInitable */ {
var another_stored:String
required init ( string:String ) {
another_stored = "B-store"
super.init(string: string)
}
}
func maker<T:StringInitable>(string:String) -> T {
return T(string: string)
}
let instanceA = A(string: "test-maker-A")
let instanceB = B(string: "test-maker-B")
let makerA:A = maker("test-maker-A")
let makerB:B = maker("test-maker-B")
let typeInstanceA = _stdlib_getTypeName(instanceA)
let typeMakerA = _stdlib_getTypeName(makerA)
let typeInstanceB = _stdlib_getTypeName(instanceB)
let typeMakerB = _stdlib_getTypeName(makerB)
从结果来看,编译器似乎推断出正确的类型,但未能调用正确的初始值设定项。为什么我必须在 B 类中显式实现 StringInitable(通过删除 B 类定义中的注释进行测试)以使通用函数“maker”调用正确的初始化程序?
最佳答案
这闻起来像一个编译器错误,原因很简单:makerB
是一个 B
类型的变量,但它被分配了一个 A
的实例>。这应该是不可能的,事实上,如果您尝试打印,更普遍地访问 makerB
变量的 another_stored
属性,则会引发运行时异常,我不会期待别的。
那是因为如果B
是A
的子类,A
的实例不能赋值给B<的变量
类型(反之亦然)。
虽然可以将 A
类型的变量赋值给 B
类型的变量,但前提是:
A
到B
的显式向下转换(否则编译器会出错)A
变量引用的实例实际上是 B
的实例(否则会引发运行时异常)请注意,编译器不仅没有调用正确的初始化程序——它还调用了另一个类的初始化程序
关于inheritance - Swift 协议(protocol)继承和泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26220610/
我是一名优秀的程序员,十分优秀!