Swift 4 无法使用类型的参数列表调用 'index'
Swift 4 Cannot invoke 'index' with an argument list of type
调用数组方法时遇到问题index(of:)
。
MyClass
继承自 UIViewController
并符合 MyDelegate
协议。
//self.viewControllers: [(UIViewController & MyDelegate)]
guard let myController = viewController as? MyClass,
let index = self.viewControllers.index(of: myController) else {return}
然后我得到错误:
Cannot invoke 'index' with an argument list of type '(of: (UIViewController & MyDelegate))'
我该如何解决这个问题,是否有比在扩展中实施 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
}
}
这几乎可以肯定只是协议(又名存在主义). So the class existential 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
符合。然而,实际上这应该是一个明确的案例,即存在 应该总是 能够符合自身,所以我继续 filed a bug.
在修复之前,一个简单的解决方案就是对具体类型进行中间转换——因此在我们的示例中,我们可以这样做:
foo(f as Foo)
在你的例子中,你可以这样做:
let index = (self.viewControllers as [UIViewController]).index(of: myController)
调用数组方法时遇到问题index(of:)
。
MyClass
继承自 UIViewController
并符合 MyDelegate
协议。
//self.viewControllers: [(UIViewController & MyDelegate)]
guard let myController = viewController as? MyClass,
let index = self.viewControllers.index(of: myController) else {return}
然后我得到错误:
Cannot invoke 'index' with an argument list of type '(of: (UIViewController & MyDelegate))'
我该如何解决这个问题,是否有比在扩展中实施 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
符合。然而,实际上这应该是一个明确的案例,即存在 应该总是 能够符合自身,所以我继续 filed a bug.
在修复之前,一个简单的解决方案就是对具体类型进行中间转换——因此在我们的示例中,我们可以这样做:
foo(f as Foo)
在你的例子中,你可以这样做:
let index = (self.viewControllers as [UIViewController]).index(of: myController)