Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 在Swift中实例化泛型类型的对象_Generics_Swift - Fatal编程技术网

Generics 在Swift中实例化泛型类型的对象

Generics 在Swift中实例化泛型类型的对象,generics,swift,Generics,Swift,我在Swift中实现了一个类Foo,它应该实例化SuperBar的给定子类的对象,例如Bar:SuperBar。我非常喜欢Swift中的泛型,因此我尝试通过以下方式实现它: class Foo<T: SuperBar> { func instantiateObject() -> T { return T() } } class SuperBar { } class Bar: SuperBar { } let foo = Foo<

我在Swift中实现了一个类
Foo
,它应该实例化
SuperBar
的给定子类的对象,例如
Bar:SuperBar
。我非常喜欢Swift中的泛型,因此我尝试通过以下方式实现它:

class Foo<T: SuperBar> {

    func instantiateObject() -> T {
        return T()
    }

}

class SuperBar {

}

class Bar: SuperBar {

}

let foo = Foo<Bar>()

let obj = foo.instantiateObject()
class-Foo{
func实例化对象()->T{
返回T()
}
}
类超级棒{
}
类别栏:超级栏{
}
设foo=foo()
设obj=foo.instanceObject()
您可以在Xcode游乐场中运行代码段,并观察到
obj
的类型是
SuperBar
,而不是
Bar
,尽管当我Alt单击常量名称时它会显示
Bar


有什么想法吗?:)

如果将
必需的init(){}
添加到
超级条
,它会正常工作。无论如何,该要求都应该是必需的,因为您是从变量类创建实例的


它允许您使用不需要的初始值设定项创建它,这是一个错误。

将类init标记为
必需的,然后调用init:

class SuperBar {
    required init() {
    }
}


class Foo<T: SuperBar> {

    func instantiateObject() -> T {
        return T.init()
    }

} 
class超级条{
必需的init(){
}
}
福班{
func实例化对象()->T{
返回T.init()
}
} 

如果您确切知道泛型的类型,您可以强制强制转换它

let emptyObject:T = NSObject() as! T
显然,这违背了泛型类的目的,但是它对于一些默认值或基类功能很有用,就像我的例子一样

如果类型
T
不是
NSObject

  • 使用
    protocol
    定义
    init
    方法的蓝图
  • 采用此
    可初始化
    协议的其他类必须实现
    init
    函数
  • 将函数与
    泛型类型一起使用
    ,以创建类型的实例
协议可初始化{
init()
}
类SuperBar:可初始化{
必需的init(){
打印(“初始超级条”)
}
}
类别栏:超级栏{
必需的init(){
打印(“初始条”)
}
}
func createInstance(类型:T.type)->T其中T:Initializable{
返回类型。init()
}
测试:

let a=createInstance(类型:SuperBar.self)
打印(“超级条:\(a.self)”)
设b=createInstance(类型:Bar.self)
打印(“条:\(b.self)”)
结果:

init SuperBar
SuperBar: __lldb_expr_22.SuperBar
init Bar
init SuperBar
Bar: __lldb_expr_22.Bar

这可能是当前版本Swift的一个缺点;考虑如果您将类型作为参数传递,例如
init(t:t.type){…t()}
似乎也不起作用,但它初始化了垃圾(null)对象这肯定会使所有非NSObject类型崩溃。