[英]Typed array of generic classes
Consider the following simplified protocol/class hierarchy考虑以下简化的协议/类层次结构
protocol P {
}
class A: P {
}
class B: P {
}
class C<T: P> {
}
I want to create a typed array of instances of the class C
.我想创建一个
C
类实例的类型化数组。 The automatic type inference does not seem to work, however.然而,自动类型推断似乎不起作用。 When I do
当我做
let objs = [C<A>(), C<B>()]
let obj = objs[0]
objs
and obj
are of type [AnyObject]
and AnyObject
, respectively. objs
和obj
是类型的[AnyObject]
和AnyObject
分别。 I would have expected something like我会期待类似的东西
let objs:[C<P>] = [C<A>(), C<B>()]
to work but it doesn't compile with the error工作,但它没有编译错误
Using 'P' as a concrete type conforming to protocol 'P' is not supported
Omitting the generic type altogether like so像这样完全省略泛型类型
let objs:[C] = [C<A>(), C<B>()]
produces a different error on compilation编译时产生不同的错误
Cannot convert value of type 'NSArray' to specified type '[C]'
Is there any way I could create an array of C
instances with a type more specific than [AnyObject]
?有什么方法可以创建一个类型比
[AnyObject]
更具体的C
实例数组?
Consider following code:考虑以下代码:
// DOES NOT WORK!!
protocol P {
var name: String { get }
}
class A: P {
var name = "A"
}
class B: P {
var name = "B"
}
class C<T: P> {
var val: T
init(val: T) {
self.val = val
}
}
let objs: [C<P>] = [ C<A>(A()) ]
let firstObj: C<P> = obj[0]
firstObj.val = B()
In this case, firstObj
is actually a C<A>
instance.在这种情况下,
firstObj
实际上是一个C<A>
实例。 But firstObj.val
must accept B()
because firstObj.val
is constrained to P
and B
conforms to P
.但是
firstObj.val
必须接受B()
因为firstObj.val
被约束到P
而B
符合P
。 This is illegal you know.你知道这是违法的。 That is why you cannot cast
C<A>
as C<P>
这就是为什么你不能将
C<A>
为C<P>
To workaround this, for example, you can create some wrapper around the C
:例如,要解决此问题,您可以围绕
C
创建一些包装器:
protocol P {
var name: String { get }
}
class A: P {
var name = "A"
}
class B: P {
var name = "B"
}
class C<T: P> {
var val: T
init(_ val: T) {
self.val = val
}
}
/// Type erasing wrapper around C that has accessor for `C.val`
struct AnyC {
let _val: () -> P
var val: P { return _val() }
init<T>(_ c: C<T>) {
_val = { return c.val }
}
}
let objs:[AnyC] = [
AnyC( C<A>(A()) ),
AnyC( C<B>(B()) ),
]
objs[0].val.name // -> "A"
objs[1].val.name // -> "B"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.