Как вызывать статические методы протокола, если они определены в расширении протокола?

protocol Car {
    static func foo() 
}

struct Truck : Car {

}

extension Car {
    static func foo() {
        print("bar")
    }
}

Car.foo() // Does not work  
// Error: Car does not have a member named foo

Truck.foo() // Works

Xcode автоматически заполняет Car.foo() правильно, поэтому я спрашиваю, является ли это ошибкой, которую он не компилирует (говорит, что у него нет члена с именем foo()). Можно ли вызывать статические методы непосредственно в протоколе, если они определены в расширении протокола?


person bogen    schedule 14.08.2015    source источник
comment
Автомобиль не является объектом, поэтому вы не можете отправлять ему сообщения.   -  person matt    schedule 14.08.2015
comment
Мне это кажется ошибкой. Поскольку реализация по умолчанию привязывает фактическую функциональность непосредственно к протоколу, она должна быть доступна для вызова в самом протоколе.   -  person hennes    schedule 14.08.2015
comment
@hennes реализация по умолчанию связывает фактическую функциональность непосредственно с протоколом, это неверное утверждение. Реализация по умолчанию связывает функциональность с классом и структурами, которые соответствуют протоколу. Существуют причины, по которым протоколы не имеют реализации.   -  person Jeffery Thomas    schedule 14.08.2015
comment
Что кажется ошибкой, так это то, что Xcode фактически предлагает автозаполнение, если это невозможно, этого делать не следует.   -  person bogen    schedule 14.08.2015


Ответы (2)


Apple документ

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

Поэтому вы не можете вызывать статические методы непосредственно протокола.

person Tikhonov Alexander    schedule 14.08.2015
comment
Они могут сделать это с помощью простого взлома. Вот мой связанный ответ. stackoverflow.com/a/59275651/1163992 - person accfews; 12.12.2019

Нет, сообщение об ошибке нехорошее, но оно говорит вам правильные вещи.

Подумайте об этом так, у вас не может быть

protocol Car {
    static func foo() {
        print("bar")
    }
}

Это компилируется с ошибкой «Методы протокола могут не иметь тел».

Расширения протоколов не добавляют возможностей к протоколам, которых не существует.

person Jeffery Thomas    schedule 14.08.2015
comment
В расширениях протокола Swift 2 можно добавлять реализации по умолчанию. - person hennes; 14.08.2015
comment
@hennes Да, они добавляют реализации по умолчанию к классам и структурам… не к протоколам. Протокол не имеет реализации. - person Jeffery Thomas; 14.08.2015
comment
Это говорит об обратном, или я ошибаюсь? - person hennes; 14.08.2015
comment
@hennes Протоколы можно расширить, чтобы предоставить реализации методов и свойств для соответствующих типов. Новое расширение протокола добавляется к классу или структуре, соответствующей протоколу, но протокол остается просто протоколом. Протоколы не имеют реализации. - person Jeffery Thomas; 14.08.2015
comment
Итак, дело в том, что реализация по умолчанию добавляется к каждому соответствующему классу/структуре вместо протокола. Я вижу вашу точку зрения. Тем не менее, это кажется мне немного странным. - person hennes; 14.08.2015