我在调用数组方法index(of:)
时遇到问题。 MyClass
继承自UIViewController
并符合MyDelegate
协议。
//self.viewControllers: [(UIViewController & MyDelegate)]
guard let myController = viewController as? MyClass,
let index = self.viewControllers.index(of: myController) else {return}
然后我得到错误:
无法使用类型为"(of: (UIViewController & MyDelegate(("的参数列表调用"index">
如何解决此问题,是否有比在扩展中实现index(of:)
更好的解决方案?
extension Array where Element == (UIViewController & MyDelegate) {
func index(of: Element) -> Int? {
for i in 0..<self.count {
if self[i] == of {
return i
}
}
return nil
}
}
这几乎可以肯定只是协议(又名存在主义(不符合自身这一事实的延伸。所以阶级存在UIViewController & MyDelegate
不符合Equatable
,即使UIViewController
符合
由于index(of:)
被限制为在具有Equatable
元素的Collection
上调用,因此无法在[UIViewController & MyDelegate]
上调用它。
下面是一个更简洁的示例:
protocol P {}
protocol X {}
class Foo : P {}
func foo<T : P>(_ t: T) {}
func bar(_ f: Foo & X) {
// error: Protocol type 'Foo & X' cannot conform to 'P' because only concrete
// types can conform to protocols
foo(f)
}
我们不能f
作为论据传递给foo(_:)
,因为Foo & X
不符合P
,即使Foo
符合。然而,这实际上应该是一个明确的案例,存在主义应该总是能够符合自己,所以我继续提交了一个错误。
在固定之前,一个简单的解决方案就是对混凝土类型进行中间浇铸——所以在我们的例子中,我们可以做到:
foo(f as Foo)
在您的示例中,您可以执行以下操作:
let index = (self.viewControllers as [UIViewController]).index(of: myController)