[英]Casting subclass from base class where subclass has generic in Swift
我有一个基类类型和一个子类类型,其中子类包含泛型类型。 如果我以子类类型的形式存储子类但我想将其转换回子类型,Swift似乎不会让我。
以下是我的意思的一个例子:
class Base {
}
class Next<T> : Base where T : UIView {
var view: T
init(view: T) {
self.view = view
}
}
let a: [Base] = [Next(view: UIImageView()), Next(view: UILabel())]
for item in a {
if let _ = item as? Next {
print("Hey!")
}
}
为什么"Hey!"
从来没打印?
编辑:
"Hey!"
如果演员读取:
if let _ item as? Next<UIImageView> ...
但仅适用于UIImageView类的情况。
和
"Hey!"
如果数组a
中的a
项目是:
Next(view: UIView())
理想情况下,我不想知道通用在铸造时的类型,但我意识到这可能是不可能的。
通用Next<T>
是一种创建唯一单独类的排序模板。 Next<UIView>
和Next<UIImageView>
是两个完全不相关的类型。
您可以将它们与协议联合起来:
class Base {
}
class Next<T> : Base where T : UIView {
var view: T
init(view: T) {
self.view = view
}
}
protocol NextProtocol { }
extension Next: NextProtocol { }
let a: [Base] = [Next(view: UIImageView()), Next(view: UILabel()), Base()]
for item in a {
if item is NextProtocol {
print("Hey!")
} else {
print("Only a Base")
}
}
输出:
Hey! Hey! Only a Base
通过定义NextProcotol
类的协议,所有从Next<T>
派生的类都符合,您可以将它们称为一个组,并将它们与从Base
派生的其他类区分开来。
注意:要检查某个item
是否属于某个类型,请使用is
而不是检查条件转换是否as?
作品。
当我看到你的例子时,我期望它在编译期间失败。
似乎只要为T指定一个具体的基类(在本例中为UIView),编译器就可以在as
或is
语句中推断出该类。 那么当你输入item as? Next
item as? Next
,编译器将item as?
理解item as?
下一个`因为UIView是一个具体的类型。
如果不使用UIView,您将使用协议,这将无效。 另外,简单地使用Next
而不是Next<UIView>
(或Next<concrete subclass of UIView>
)将导致在is
或as
语句之外的编译器错误。
这是协议有用的地方。
你需要一个虚拟协议来确认它Next
并使用该伪协议来检查您的项目类型。
因此,我们在它Next
创建一个伪协议确认并使用该协议来比较items
。
代码就是这样的。
class Base {
}
class Next<T> : Base where T : UIView {
var view: T
init(view: T) {
self.view = view
}
}
protocol MyType {
}
extension Next: MyType {}
let a: [Base] = [Next(view: UILabel()), Next(view: UILabel())]
for item in a {
if let _ = item as? MyType {
print("Hey!")
}
}
UIView
是所有UIElements
超级类。
说这会导致真实,
if let _ = UILabel() as? UIView {print("yes") }
Next
没有向UIView
确认,而是需要向UIView
确认的内容因此你不能使用UIView
来检查它们是否是Next
,接下来没有确切的类型,
这里我们使用上面的伪协议!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.