为什么这个Swift代码没有编译?
protocol P { }
struct S: P { }
let arr:[P] = [ S() ]
extension Array where Element : P {
func test<T>() -> [T] {
return []
}
}
let result : [S] = arr.test()
Run Code Online (Sandbox Code Playgroud)
编译器说:"类型P不符合协议P"(或者,在Swift的更高版本中,"不支持使用'P'作为符合协议'P'的具体类型.").
为什么不?不知怎的,这感觉就像语言中的漏洞.我意识到问题源于将数组声明arr为协议类型的数组,但这是不合理的事情吗?我认为协议正是为了帮助提供类似层次结构的结构?
我正在尝试创建一个简单的协议,说明对象是处于"开启"状态还是"关闭"状态.对此的解释取决于实施对象.对于a UISwitch,无论开关是打开还是关闭(duh).对于a UIButton,可能是按钮是否处于selected状态.对于a Car,可能是汽车的引擎是否打开,或者即使它是否在移动.所以我开始创建这个简单的协议:
protocol OnOffRepresentable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
Run Code Online (Sandbox Code Playgroud)
现在我可以扩展前面提到的UI控件,如下所示:
extension UISwitch: OnOffRepresentable {
func isInOnState() -> Bool { return on }
func isInOffState() -> Bool { return !on }
}
extension UIButton: OnOffRepresentable {
func isInOnState() -> Bool { return selected }
func isInOffState() -> Bool { return !selected }
}
Run Code Online (Sandbox Code Playgroud)
现在我可以创建这些类型的对象的数组并循环它,检查它们是打开还是关闭:
let booleanControls: [OnOffRepresentable] = [UISwitch(), UIButton()]
booleanControls.forEach { print($0.isInOnState()) }
Run Code Online (Sandbox Code Playgroud)
大!现在我想创建一个将这些控件映射到a的字典,UILabel以便在控件更改状态时更改与控件关联的标签的文本.所以我去宣布我的字典:
var toggleToLabelMapper: …Run Code Online (Sandbox Code Playgroud) 我想实现以下目标;能够从数组中删除任何给定的实例。但是以下不是有效的 Swift 3 语法:
extension Array where Element: class { // error: Expected identifier for type name
mutating func remove(_ object: AnyObject) {
if let index = index(where: { $0 === object }) {
remove(at: index)
}
}
}
protocol MyProtocol: class { }
class MyClass: MyProtocol { }
var myInstance = MyClass()
var myArray: [MyProtocol] = [myInstance]
myArray.remove(myInstance)
Run Code Online (Sandbox Code Playgroud)
通用方法如何发挥作用?我不想对 MyProtocol 或 Equatable 的通用扩展进行特殊处理。
我想删除重复的代码,所以我想创建一个简单的 MVP 基础视图控制器,它将模型、视图和演示者类型联系在一起并自动连接它们,例如:
class BaseMvpViewController<M: MvpModel, V: MvpView, P: MvpPresenter>: UIViewController {
Run Code Online (Sandbox Code Playgroud)
我的模型和视图是空协议的地方:
protocol MvpModel {}
protocol MvpView: class {} // class is needed for weak property
Run Code Online (Sandbox Code Playgroud)
主持人看起来像这样:
protocol MvpPresenter {
associatedtype View: MvpView
weak var view: View? { get set }
func onAttach(view: View)
func onDetach(view: View)
}
Run Code Online (Sandbox Code Playgroud)
这是我的全部BaseMvpViewController:
class BaseMvpViewController<M: MvpModel, V, P: MvpPresenter>: UIViewController, MvpView {
typealias View = V
var model: M? = nil
var presenter: P!
required public init?(coder aDecoder: NSCoder) {
super.init(coder: …Run Code Online (Sandbox Code Playgroud)