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_Wildcard - Fatal编程技术网

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'