test1_1 и test1_2 используют existential, а test2_1 и test2_2 выражают generic-параметр. Вызов A().test2_2(value: B()) корректен: B соответствует протоколу.
protocol SomeProtocol {}
test1_1 и test1_2 используют existential, а test2_1 и test2_2 выражают generic-параметр. Вызов A().test2_2(value: B()) корректен: B соответствует протоколу.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
protocol SomeProtocol {}
func test1_1(value: SomeProtocol) {} func test1_2(value: any SomeProtocol) {}
func test2_1(value: some SomeProtocol) {} func test2_2<Value: SomeProtocol>(value: Value) {}
class A { func test2_2<Value: SomeProtocol>(value: Value) { } }
class B: SomeProtocol { }
A().test2_2(value: B())
Ответ
test1_1 и test1_2 используют existential, а test2_1 и test2_2 выражают generic-параметр. Вызов A().test2_2(value: B()) корректен: B соответствует протоколу.
some SomeProtocol в параметре — сокращение ограничения generic-типа, выбранного вызывающей стороной. any явно обозначает existential-контейнер; допустимость голого имени протокола зависит от режима языка.
Метод класса A сам generic: экземпляр A не обязан иметь общий параметр Value. В конкретном вызове Value выводится как B. Ни метод, ни конструкторы из примера ничего не печатают. Важно не смешивать some в аргументе с opaque return type, где конкретный возвращаемый тип выбирает реализация.
Источник: raw.githubusercontent.com.