Ответ 1
Это действительно невозможно из коробки в Swift. Для этого вам нужно создать новый протокол, объявленный любыми методами и операторами, которые вы собираетесь использовать в своей общей функции. Этот процесс будет работать для вас, но точные детали будут зависеть от того, что делает ваша общая функция. Вот как вы это сделаете для функции, которая получает число n
и возвращает (n - 1)^2
.
Сначала определите свой протокол с операторами и инициализатором, который принимает Int
(чтобы мы могли вычесть его).
protocol NumericType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
func %(lhs: Self, rhs: Self) -> Self
init(_ v: Int)
}
Все числовые типы уже реализуют их, но на данный момент компилятор не знает, что они соответствуют новому протоколу NumericType
. Вы должны сделать это явным - Apple называет это "объявлением принятия протокола с расширением". Мы сделаем это для Double
, Float
и всех целых типов:
extension Double : NumericType { }
extension Float : NumericType { }
extension Int : NumericType { }
extension Int8 : NumericType { }
extension Int16 : NumericType { }
extension Int32 : NumericType { }
extension Int64 : NumericType { }
extension UInt : NumericType { }
extension UInt8 : NumericType { }
extension UInt16 : NumericType { }
extension UInt32 : NumericType { }
extension UInt64 : NumericType { }
Теперь мы можем написать нашу фактическую функцию, используя протокол NumericType
в качестве общего ограничения.
func minusOneSquared<T : NumericType> (number : T) -> T {
let minusOne = number - T(1)
return minusOne * minusOne
}
minusOneSquared(5) // 16
minusOneSquared(2.3) // 1.69
minusOneSquared(2 as UInt64) // 1