MyViewModelProtocol определяется как расширение ViewModelProtocol
Правильно.MyViewModelProtocol extends ViewModelProtocol.Это не не соответствует ViewModelProtocol.Это классический случай «протоколы не соответствуют самим себе».Для вашего связанного типа требуется, чтобы ViewModel был конкретным типом, соответствующим ViewModelProtocol, а MyViewModelProtocol не является конкретным типом и ни к чему не соответствует (протоколы не соответствуют протоколам).
Способ решения этой проблемыдолжен начинаться с вызывающего кода , а затем создавать протоколы, поддерживающие то, как вы хотите, чтобы вызывающий код выглядел.В приведенном вами коде правильное решение - полностью избавиться от ModeledView.Это ничего не делает;ничто не полагается на это, и это не обеспечивает никаких расширений.Я предполагаю, что в вашем "реальном" коде что-то действительно полагается на это.Это ключевой кусок кода, на котором нужно сосредоточиться.Лучший способ добиться этого - написать несколько конкретных примеров типов соответствия, которые вы хотели бы существовать.(Если у вас возникли проблемы при написании нескольких конкретных реализаций, то пересмотрите, есть ли что-то, что нужно абстрагировать.)
Просто для более подробного объяснения, почему это не будет работать в вашем конкретном случае (это не будет работатьв более общих случаях также, но ваш случай накладывает дополнительные ограничения, которые важны).Вы потребовали, чтобы типы, которые соответствуют ViewModelProtocol, также соответствовали Equatable.Это означает, что они должны реализовать:
static public func == (lhs: Self, rhs: Self) -> Bool {
Это не означает, что некоторый тип, соответствующий ViewModelProtocol, может быть эквивалентен другому типу, соответствующему ViewModelProtocol.Это означает Self
, конкретный, конкретный тип, реализующий протокол.ViewModelProtocol не сам по себе Equatable.Если бы это было так, какой код выше вы бы ожидали dataModel == myViewModel
для вызова?Будет ли это проверить bar
или нет?Помните, ==
это просто функция.Свифт не знает, что вы спрашиваете «равны ли они».Он не может вводить такие вещи, как «если они разные конкретные типы, они не равны».Это то, что сама функция должна делать.И поэтому Swift нужно знать, какую функцию вызывать.
Возможность сделать это в Swift станет важным дополнением к языку.Это обсуждалось довольно часто (см. Ссылку, которую я разместил в предыдущих комментариях), но это как минимум несколько выпусков.
Если вы удалите требование Equatable
, оно все равно не будет работать сегодня, нотребуемая смена языка намного меньше (и может наступить раньше).