rfr*_*lli 17 generics swift xcode6
我正在尝试基于指定的泛型类型转换和/或生成变量.我知道swift中没有类型擦除,但它似乎不是泛型保留类型,而不是通用的指定条件,例如符合基类.似乎所有我可以投射或初始化的是基类.更奇怪的是,当我在调试器中时,泛型似乎有一个RawPointer到正确的类,甚至变量看起来像他们是正确的类型:
编辑:
从Xcode 6.1开始,这仍然是个问题(简化代码由Gregory Higley提供):
class BaseClass {
func printme() -> Void {
println("I am BaseClass")
}
}
class DerivedClass : BaseClass {
override func printme() -> Void {
println("I am DerivedClass")
}
}
class Util<T: BaseClass> {
func doSomething() {
var instance = T()
instance.printme()
}
}
var util = Util<DerivedClass>()
util.doSomething()
Run Code Online (Sandbox Code Playgroud)
仍打印出"我是BaseClass"
还要注意基类中所需的init {}不再有效.

rin*_*aro 15
此代码按预期工作.
class BaseClass {
required init() {} // <-- ADDED THIS
func printme() -> Void {
println("I am BaseClass")
}
}
class DerivedClass : BaseClass {
override func printme() -> Void {
println("I am DerivedClass")
}
}
class Util<T: BaseClass> {
func doSomething() {
var instance = T()
instance.printme()
}
}
var util = Util<DerivedClass>()
util.doSomething()
Run Code Online (Sandbox Code Playgroud)
代码库是从@GregoryHigley偷来的:)
标记init() {}为required事情.这个保证init()是来自任何派生类的指定初始值设定项BaseClass.
没有它,人们就可以制作非法的子类:
class IllegalDerivedClass : BaseClass {
var name:String
init(name:String) {
self.name = name
super.init()
}
override func printme() -> Void {
println("I am DerivedClass")
}
}
var util = Util<IllegalDerivedClass>()
util.doSomething()
Run Code Online (Sandbox Code Playgroud)
您知道这不起作用,因为IllegalDerivedClass 不继承init()初始化程序.
我想,这就是你问题的原因.
无论如何,谁的错?
DerivedClass()按照指定初始化T.instance是BaseClass实际的实例.添加:
从Xcode 6.1 GM 2开始,看来你需要做更多的工作.(除此之外required init() {})
class Util<T: BaseClass> {
let theClass = T.self // store type itself to variable
func doSomething() {
var instance = theClass() // then initialize
instance.printme()
}
}
Run Code Online (Sandbox Code Playgroud)
我完全不知道为什么我们需要这个,X上发生了什么(
新增:2014年10月18日
我发现这也有效:
func doSomething() {
var instance = (T.self as T.Type)()
instance.printme()
}
Run Code Online (Sandbox Code Playgroud)
增加日期:2015/02/10
从Xcode版本6.3(6D520o)/ Swift 1.2开始
我们不再需要(T.self as T.Type)()黑客攻击.只要有初始化程序就T()可以工作.Trequired init()
class Util<T: BaseClass> {
func doSomething() {
var instance = T()
instance.printme()
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个简化版的代码,如下所示:
class BaseClass {
func printme() -> Void {
println("I am BaseClass")
}
}
class DerivedClass : BaseClass {
override func printme() -> Void {
println("I am DerivedClass")
}
}
class Util<T: BaseClass> {
func doSomething() {
var instance = T()
instance.printme()
}
}
var util = Util<DerivedClass>()
util.doSomething()
Run Code Online (Sandbox Code Playgroud)
这就解决了问题的本质.人们期望util.doSomething()打印"我是DerivedClass",但每次打印"我都是BaseClass".这必须是一个错误,因为没有合理的类型系统会以这种方式工作.
我认为你应该把它作为一个bug提交给Apple.
| 归档时间: |
|
| 查看次数: |
2955 次 |
| 最近记录: |