Допустим, у меня есть эти протоколы:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Теперь, если мне нужна функция, которая принимает общий тип, но этот тип должен соответствовать, SomeProtocol
я мог бы сделать:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Но есть ли способ добавить ограничение типа для нескольких протоколов?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
В подобных вещах используются запятые, но в этом случае начнется объявление другого типа. Вот что я попробовал.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Ответы:
Вы можете использовать предложение where, которое позволяет указать столько требований, сколько вы хотите (все из которых должны быть выполнены), через запятую.
Свифт 2:
Свифт 3 и 4:
или более мощное предложение where:
Вы, конечно, можете использовать состав протокола (например,
protocol<SomeProtocol, SomeOtherProtocol>
), но он немного менее гибкий.Использование
where
позволяет работать со случаями, когда задействованы несколько типов.Вы все равно можете захотеть составить протоколы для повторного использования в нескольких местах или просто дать составленному протоколу осмысленное имя.
Свифт 5:
Это кажется более естественным, поскольку протоколы находятся рядом с аргументом.
источник
<T where T:SomeStruct, T:AnotherStruct>
? Для классов компилятор, кажется, интерпретирует это как высказывание «T является подклассом обоих», а для структур он просто жалуется на это"Type 'T' constrained to non-protocol type"
.where
предложение для дополнительного типа / другого использования, например,func someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
для псевдонимов типовSubType
в, напримерSomeProtocol
.У вас есть две возможности:
Вы используете предложение where, как указано в ответе Jiaaro:
Вы используете тип композиции протокола :
источник
typealias
. Спасибо!Эволюция Swift 3.0 внесла некоторые изменения. Теперь два наших варианта выглядят немного иначе.
Использование
where
предложения в Swift 3.0:Предложение
where
теперь перемещено в конец сигнатуры функции, чтобы улучшить читаемость. Итак, множественное наследование протоколов теперь выглядит так:Использование
protocol<>
конструкции в Swift 3.0:Композиция с использованием
protocol<>
конструкции устарела. Ранееprotocol<SomeProtocol, SomeOtherProtocol>
теперь выглядит так:Ссылки.
Подробнее об изменениях для
where
здесь: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdИ подробнее об изменениях для конструкции protocol <> можно прочитать здесь: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
источник
Swift 3 предлагает до 3 различных способов объявления вашей функции.
1. Использование
&
оператора2. Использование
where
предложения3. Использование
where
предложения и&
оператораТакже обратите внимание, что вы можете использовать
typealias
для сокращения объявления функции.источник