Метод ... в не финальном классе ... не может быть реализован в расширении протокола, потому что он возвращает 'Self' и имеет связанные требования типа - PullRequest
2 голосов
/ 21 октября 2019

Это мой код:

protocol Person {
    associatedtype Homework

    static func generate(homeWork: Homework) -> Self
}

extension Person {
    static func generate(homeWork: Homework) -> Self {
        fatalError()
    }
}

// Method 'generate(homeWork:)' in non-final class 'Teacher' 
// cannot be implemented in a protocol extension because it 
// returns 'Self' and has associated type requirements
class Teacher: Person {
    typealias Homework = Int
}

Несмотря на странное именование типов, мне любопытно, почему невозможно согласовать неконечный класс с протоколом, в котором есть метод, который возвращает Self и с associatedtype в качестве типа параметра.

Примечание: я не спрашиваю, как решить эту проблему (потому что я могу просто пометить свой class final). Я хочу знать, почему это невозможно.

Я думаю, что это странно. Протоколы с associatedtypes и Self всегда являются проблемой, но при использовании одного из двух (возвращая Self / associatedtype тип протокола в параметре) код компилируется просто отлично.

Почему я не могу соответствовать протоколу, который имеет реализацию метода по умолчанию, в то время как метод имеет тип возврата Self и associatedtype в параметре, но при использовании только одногоиз них код компилируется? Почему обе проблемы возникают при работе с инергентностью (поскольку маркировка class как final исправляет сообщение об ошибке, поэтому должно быть что-то с инерционностью)?

1 Ответ

0 голосов
/ 21 октября 2019

Похоже, это из-за ограничений компилятора. Вот некоторые уместные обсуждения от людей из команды Swift: https://twitter.com/_danielhall/status/737782965116141568

Оригинальный твит показывает, что произойдет, если мы попытаемся создать подкласс из Teacher, компилятор не сможет определить его как соответствующийк протоколу Person.

Особенно актуально для команды swift в этой теме: «Мы не поддерживаем подтип при сопоставлении требований протокола. Я считаю, что в языке отсутствует функция»

Таким образом, зная, что компилятор не может распознать подклассы как соответствующие протоколу, в этих ситуациях он решает форсировать финальный класс.

...