Как предоставить пользовательские функции min и max для типа в Swift? - PullRequest
0 голосов
/ 22 декабря 2018

Я портирую свою библиотеку векторной и геометрической математики с C ++ на swift и испытываю затруднения, связанные с ограничениями типов на обобщениях.Одно конкретное затруднение - мин / макс.Рассмотрим очень простой универсальный класс Vector2:

public protocol Vectorable : Numeric & Initializable {}

extension Float : Vectorable {}
extension Double : Vectorable {}
extension Int32 : Vectorable {}

struct Vector2<T : Vectorable> : CustomStringConvertible, Equatable {

   var x : T
   var y : T

    ....
}

А вот мои (определяемые пользователем глобально области) функции min / max, определенные по компонентам, которые вызывают стандартную библиотеку min / max для значений компонентов:

func min <T : Comparable> (lhs : Vector2<T>, rhs : Vector2<T>) -> Vector2<T> {
   return Vector2<T>(min(lhs.x, rhs.x), min(lhs.y, rhs.y))
}

func max <T : Comparable> (lhs : Vector2<T>, rhs : Vector2<T>) -> Vector2<T> {
   return Vector2<T>(max(lhs.x, rhs.x), max(lhs.y, rhs.y))
}

Однако это не работает.Когда я пытаюсь использовать эти функции min и max для значений типа Vector2, компилятор выдает следующую жалобу:

src / math / Vector2.swift: 167: 19: ошибка: тип аргумента 'Vector2f'(он же Vector2') не соответствует ожидаемому типу 'Comparable'
let d = min (a, b)

Я не понимаю, почему Vector должен соответствовать ComparableВот.Нет, где я могу вызвать глобальный оператор min / max для объекта Vector, он применяется только к компонентам, которые имеют тип T: Comparable и на самом деле просто Float.

Похоже, что компилятор игнорирует мои определения min / max и пытается применить версию библиотеки std.

1 Ответ

0 голосов
/ 22 декабря 2018

Несмотря на отсутствие необходимой информации, я смог воспроизвести проблему, сделав некоторые упущения и допуски, например:

public protocol Vectorable : Numeric {}

extension Float : Vectorable {}
extension Double : Vectorable {}
extension Int32 : Vectorable {}

struct Vector2<T : Vectorable> :  Equatable {
    var x : T
    var y : T
}

func min <T : Comparable> (lhs : Vector2<T>, rhs : Vector2<T>) -> Vector2<T> {
    return Vector2<T>(x:min(lhs.x, rhs.x), y:min(lhs.y, rhs.y))
}

func max <T : Comparable> (lhs : Vector2<T>, rhs : Vector2<T>) -> Vector2<T> {
    return Vector2<T>(x:max(lhs.x, rhs.x), y:max(lhs.y, rhs.y))
}


class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let v1 = Vector2(x: 1.0, y: 1.0)
        let v2 = Vector2(x: 2.0, y: 2.0)
        let v3 = min(v1,v2) // error
    }
}

, что дает нам сообщение об ошибке:

enter image description here

Ну, в этом случае проблема заключается только в пропущенных подчеркиваниях в ваших объявлениях функций:

func min <T : Comparable> (_ lhs : Vector2<T>, _ rhs : Vector2<T>) -> Vector2<T> {

и

func max <T : Comparable> (_ lhs : Vector2<T>, _ rhs : Vector2<T>) -> Vector2<T> {
...