Ассоциированный тип по умолчанию с использованием расширения протокола

У меня есть протокол с associatedType. Я хочу указать значение по умолчанию typealias для этого типа в расширении протокола. Это должно быть сделано только для классов, которые наследуются от определенного класса.

protocol Foo: class {
  associatedtype Bar
  func fooFunction(bar: Bar)
}

Расширение протокола:

extension Foo where Self: SomeClass {
  typealias Bar = Int
  func fooFunction(bar: Int) {
    // Implementation
  }
}

Компилятор жалуется, что 'Bar' is ambiguous for type lookup in this context. Я не смог найти ничего полезного и в быстрой книге.


person Ayush Goel    schedule 28.05.2016    source источник


Ответы (2)


У меня была такая же проблема, и со Swift 4 (возможно, и в более ранней версии, я не тестировал) вы можете просто добавить значение по умолчанию для своего associatedtype в его определение:

protocol Foo: class {
  associatedtype Bar = Int  // notice the "= Int" here
  func fooFunction(bar: Bar)
}

Для этого не нужно добавлять расширение к вашему протоколу.

(Я не смог найти упоминания об этом в документе, но для меня это сработало, как и ожидалось, и кажется естественным написать это таким образом. Если вы можете дать ссылку на какой-либо авторитетный источник, пожалуйста, не стесняйтесь редактировать его в ответ)

person Guillaume Algis    schedule 27.06.2018

В контексте расширения доступны два связанных типа Bar, и компилятор не может определить правильный. Попробуй это.

protocol Foo: class {
  associatedtype Bar
  func fooFunction(bar: Bar)
}

extension Foo where Self: SomeClass {
  func fooFunction(bar: SomeClass.Bar) {}
}

class SomeClass:Foo{
  typealias Bar = Int
}
person Khundragpan    schedule 28.05.2016
comment
Это именно то, чего я не хочу делать. Я хочу, чтобы мой класс просто соответствовал протоколу и получал реализацию по умолчанию в зависимости от его типа. - person Ayush Goel; 28.05.2016
comment
Кстати, вы можете просто сказать func fooFunction(bar: Bar) {} в своей реализации протокола. Он автоматически выберет тип, связанный с соответствующим классом. Нет необходимости в SomeClass.Bar. - person Ayush Goel; 28.05.2016