Я пытаюсь написать универсальную функцию в Swift, которая принимает любое число, Int
, Float
, Double
и т. Д., Устанавливая универсальный тип в <T: Numeric>
. Таким образом,
func doSomething<T: Numeric>(with foo: T, and bar: T) -> T {
// body
}
Большая часть тела будет работать для любого типа Numeric
, но по пути мне нужно найти остаток ... что означает, что мне нужен другой подход для FloatingPoint
типов по сравнению с Integer
типами.
Когда T
является Int
, это означает использование оператора по модулю:
let remainder = foo % bar
Однако, когда T
- это Double
или Float
, оператор по модулю не работает, и мне нужно использовать метод truncatingRemainder(dividingBy:)
:
let remainder = foo.truncatingRemainder(dividingBy: bar)
Я борюсь за то, чтобы найти способ отсеять это. Теоретически, я должен быть в состоянии сделать что-то вроде этого:
var remainder: T
if T.self as FloatingPoint { // <- This doesn't work
remainder = foo.truncatingRemainder(dividingBy: bar)
} else {
remainder = foo % bar
}
Это, конечно, приводит к этой ошибке, поскольку FloatingPoint
имеет связанный тип:
error: protocol 'FloatingPoint' can only be used as a generic constraint because it has Self or associated type requirements
Я понимаю эту ошибку ... по сути, FloatingPoint
является универсальным с все еще универсальным связанным типом для определения принимающего типа.
Однако я хотел бы знать, как лучше всего условно запустить выбранные блоки кода, которые применяются только к более узко определенному протоколу, чем тот, который определен с помощью общего параметра (T
).
В частности, есть ли способ определить одну универсальную функцию для обработки всех типов Numeric
, а затем дифференцировать по FloatingPoint
против Integer
типов внутри.