Generics Swift:将通配符用作泛型类型参数
我想在字典中存储从泛型类型派生的类的实例;也就是说,字典应该存储从该泛型派生的任何类的实例 大概是这样的:Generics Swift:将通配符用作泛型类型参数,generics,swift,wildcard,Generics,Swift,Wildcard,我想在字典中存储从泛型类型派生的类的实例;也就是说,字典应该存储从该泛型派生的任何类的实例 大概是这样的: class ParentClass {} class ChildClass: ParentClass {} class GenericClass<T: ParentClass> { var foo:T? } typealias DerivedClass = GenericClass<ChildClass> class TestGenerics {
class ParentClass {}
class ChildClass: ParentClass {}
class GenericClass<T: ParentClass> {
var foo:T?
}
typealias DerivedClass = GenericClass<ChildClass>
class TestGenerics {
var dict: Dictionary<String, GenericClass<**what goes here??**>> = [:]
func test() {
var derivedClassInstance = DerivedClass()
dict.updateValue(derivedClassInstance, forKey: "name")
}
}
class父类{}
类ChildClass:ParentClass{}
类泛型类{
福娃:T?
}
typealias DerivedClass=GenericClass
类测试泛型{
变量dict:Dictionary=[:]
func测试(){
var derivedClassInstance=DerivedClass()
dict.updateValue(派生ClassInstance,forKey:“名称”)
}
}
这在Java中相当简单:
public class TestGenericsOuter {
class ParentClass {}
class ChildClass extends ParentClass {}
class GenericClass<T extends ParentClass> {
T foo;
}
class DerivedClass extends GenericClass<ChildClass> {}
class TestGenerics {
Dictionary<String, GenericClass<? extends ParentClass>> dict;
void test() {
DerivedClass derivedClassInstance = new DerivedClass();
dict.put("name", derivedClassInstance);
}
}
}
公共类TestGenericsOuter{
类父类{}
类ChildClass扩展父类{}
类泛型类{
T foo;
}
类DerivedClass扩展了GenericClass{}
类测试泛型{
Dictionary您需要参数化包含任何泛型引用的类型,并在其中使用类型约束。此外,typealias与参数化类型上的约束相关,因此它位于该类型内
class ParentClass {}
class ChildClass: ParentClass {}
class GenericClass<T: ParentClass> {
var foo:T?
}
class TestGenerics<T: ParentClass> {
typealias DerivedClass = GenericClass<T>
var dict: Dictionary<String, GenericClass<T>> = [:]
func test() {
var derivedClassInstance = DerivedClass()
dict.updateValue(derivedClassInstance, forKey: "name")
}
}
let blah = TestGenerics<ChildClass>()
let baz = GenericClass<ChildClass>()
baz.foo = ChildClass()
blah.dict = ["a":baz]
class父类{}
类ChildClass:ParentClass{}
类泛型类{
福娃:T?
}
类测试泛型{
typealias DerivedClass=GenericClass
变量dict:Dictionary=[:]
func测试(){
var derivedClassInstance=DerivedClass()
dict.updateValue(派生ClassInstance,forKey:“名称”)
}
}
设blah=TestGenerics()
设baz=GenericClass()
baz.foo=ChildClass()
blah.dict=[“a”:baz]
我认为您不能模仿Java的通配符,但您可能不需要这样做。您可以在代码需要父类的任何地方使用子类
class TestGenerics {
var dict: Dictionary<String, GenericClass<ParentClass>> = [:]
func test() {
var derivedClassInstance = GenericClass<ParentClass>()
dict.updateValue(derivedClassInstance, forKey: "name")
}
}
该代码编译时不会出错。但是,Swift不支持自定义泛型类上的协变,因此无法使用协变类型更改字典,因此无法编译以下代码:
test.dict = Dictionary<String, GenericClass<ChildClass>>()
//Error: 'ChildClass' is not identical to 'ParentClass'
test.dict=Dictionary()
//错误:“ChildClass”与“ParentClass”不相同
这不是很直观,因为本机数组和字典确实支持协方差,因此允许:
let array: Array<ParentClass> = Array<ChildClass>()
let dic: Dictionary<String, ParentClass> = Dictionary<String, ChildClass>()
let-array:array=array()
让dic:Dictionary=Dictionary()
但不是这个:
let generic: GenericClass<ParentClass> = GenericClass<ChildClass>()
//Error: 'ChildClass' is not identical to 'ParentClass'
让generic:GenericClass=GenericClass()
//错误:“ChildClass”与“ParentClass”不相同
基本上,Swift将Array
视为Array
的一个子类型,但目前无法告诉编译器GenericClass
是(或应该是)GenericClass的一个子类型
。随着语言的发展,希望能够添加一种将自定义类声明为协变类的方法。对——这就是我的意思:我可以使用一个字典,将Any作为值类型。(我把尖括号放进去,解析器会吃掉它们,我猜).我想使用一个更具体的类型限制,这样我就不必把字典里的所有东西都扔掉了。这似乎只是在“推卸责任”到TestGenerics。如果TestGenerics不应该被参数化怎么办?但是你的方法是一个特定的字典只能保存一种类型的GenericClass
,即只保存一种特定的t
。在Java中,类似字典的东西如果Swift将Array
作为Array
的子类型,那么var>时会发生什么s:Array=Array()
然后是vehicles.append(myCar)
?这是一个好问题@Andreas。刚刚在操场上尝试过,显然这是有效的代码。如果你使用vehicles.dynamicType
,它会返回vehicles是数组
,即使它是使用Array()构建的
。这是意外的。@Swift中的Asayagalvan数组类型是值类型。因此,该类型是变量的一部分,而不是值(与Java的列表
,它是引用类型不同)。Swift的数组。append()
创建一个新值并将其存储在原始变量中。如果该变量具有足够的许可类型,则可以将新值存储在该变量中。这不取决于旧值来自何处以及原始变量的类型,因为旧值和新值互不相关。
let generic: GenericClass<ParentClass> = GenericClass<ChildClass>()
//Error: 'ChildClass' is not identical to 'ParentClass'