Swift 4 Невозможно вызвать 'index' со списком аргументов типа

У меня проблема с вызовом метода массива index(of:). MyClass наследуется от UIViewController и соответствует MyDelegate протокол.

//self.viewControllers: [(UIViewController & MyDelegate)]
guard let myController = viewController as? MyClass,
let index = self.viewControllers.index(of: myController) else {return}

тогда я получаю ошибку:

  

Невозможно вызвать 'index' со списком аргументов типа '(из: (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 
    } 
}
7 голосов | спросил John Reese 11 J0000006Europe/Moscow 2017, 17:55:43

1 ответ


0

Это почти наверняка является лишь продолжением того факта, что протоколы (ака. existentials) не соответствуют самим себе , Так что класс экзистенциальный UIViewController & MyDelegate не соответствует Equatable, хотя UIViewController делает.

Поэтому, потому что index(of:) ограничено вызовом для Collection с элементами Equatable, его нельзя вызвать для [UIViewController & MyDelegate].

Вот более минимальный пример:

protocol P {}
class Foo : P {}

func foo<T : P>(_ t: T) {}

let f: (Foo & P) = Foo()
foo(f) // Cannot invoke 'foo' with an argument list of type '((Foo & P))'

Мы не можем передать f в качестве аргумента foo(_:), так как Foo & P не соответствует P, хотя Foo делает. Однако на самом деле это должен быть четкий случай, когда экзистенциальный всегда должен быть в состоянии соответствовать самому себе, поэтому я продолжил и подал ошибку .

Пока исправлено, простое решение - просто выполнить промежуточное приведение к конкретному типу - так что в нашем примере мы можем сделать:

foo(f as Foo)

и в вашем примере вы можете сделать:

let index = (self.viewControllers as [UIViewController]).index(of: myController) 
ответил Hamish 12 J0000006Europe/Moscow 2017, 00:22:33

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132