我有以下结构:
班级A
class A<T: SomeInterface> : C {
}
班级B
class B : SomeInterface {
func someFunc(param: C){
// check if param is of class A with `self.dynamicType` generic type
if let typedC = param as? A<self.dynamicType> { // does not work
}
}
}
我想检查param
是否有B
类作为通用约束。有没有办法指定通配符泛型类型?事实上,通用约束是否属于B
类型并不重要,但这也不可能:
class B : SomeInterface {
func someFunc(param: C){
// check if param is of type A
if let typedC = param as? A { // don't check generic constraint type
}
}
}
或(如果有通配符):
class B : SomeInterface {
func someFunc(param: C){
// check if param is of type A with wildcard (Is there such a thing as a wildcard?)
if let typedC = param as? A<?> { // don't require specific generic type, just enter if param is of type A
}
}
}
import UIKit
protocol SomeInterface{
func someFunc(param: C)
}
class C {
}
class A<T: SomeInterface> : C{
}
class B : SomeInterface {
func someFunc(param: C) {
// A is a subclass of C, but I want the typed generic subclass
if let typed = param as? A<self.dynamicType> {
}
}
}
let b = B()
let a = A<B>()
b.someFunc(a)
答案 0 :(得分:1)
定义时:
path
你没有定义一个类,所以是一个类型,但是一个泛型类型A,必须被实例化为某种类型。
所以,你不能用这种方式在另一个类中定义一个函数:
path
这将始终提供类型错误。相反,你应该定义:
class A<T: SomeInterface>{
}
例如,由于您已将func someFunc(paramA: A)
定义为func someFunc(paramA: A<SomeTypeSubtypeOfSomeInterface>)
的子类型,因此您可以定义:
B
答案 1 :(得分:1)
一旦开始允许非最终子类,很难表达世界变得多么复杂。如果你可以制作这些最终的类或协议,那么很多尖锐的边缘就会消失。
你说的你想要什么,而你所写的代码并没有真正排队(在处理子类时,非常常见)。所以你真正想要的是重要的。
我想检查param是否有类型B作为通用约束。
不确定。这很容易。
class B : SomeInterface {
func someFunc(param: C) {
if let typed = param as? A<B> {
print(typed)
} else {
print("NO")
}
}
}
这将在我们获得A<B>
的任何时候生效。如果我们收到A<SubClassOfB>
,即使将其传递给SubclassOfB.someFunc()
,它也无效。 (看看我的意思是微妙的?)
从您的代码中,您似乎真的想要&#34;如果我通过A<Self>
&#34;在哪里&#34;自我&#34;意味着&#34;完全是我的类,而不是超类或子类。&#34;我见过的唯一方法是使用协议扩展:
extension SomeInterface {
func someFunc(param: C) {
if let typed = param as? A<Self> {
print(typed)
} else {
print("NO")
}
}
}
这样可以将Self
替换为&#34;我的班级。&#34;但请注意,这意味着someFunc(A<MySubclass>)
无法正常工作。 A<Self>
与A<Subclass>
不同。请注意,您可以向扩展添加where
子句以限制其范围:
extension SomeInterface where Self: B { ... }
如果您的意思是&#34; T
是Self
或Self
&#34;的某些子类,也许它可能,但根据我的经验,它会得到越来越棘手和脆弱。你不能在Swift中对其参数进行协变的泛型类型,因此A<Subclass>
本身不是A<Superclass>
的子类型(这是一个比它听起来更棘手的问题,你不会& #39;总是希望它是真的)。如果你只是将B
标记为最终,这就是一种疯狂的角落案例。然后大部分老鼠的巢都消失了。