我正在将我的向量和几何数学库从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))
}
但是,这不起作用。当我尝试在Vector2类型的值上使用这些min和max函数时,编译器发出以下不满消息:
src / math / Vector2.swift:167:19:错误:参数类型为'Vector2f'(aka 'Vector2')不符合预期的类型'Comparable'
令d = min(a,b)
我不明白为什么Vector在这里需要符合Comparable。不,我在哪里不能对Vector对象调用全局min / max运算符,它仅适用于类型为T:可比较,实际上只是Float的组件。
似乎编译器正在忽略我的最小/最大定义,并尝试应用标准库版本。
答案 0 :(得分:0)
尽管缺少必要的信息,但我还是可以通过省略和保留一些地方来重现该问题,例如:
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.min.js"></script>
<div class="swiper-container swiper-scale-effect">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">
<div class="slide1 swiper-slide-cover"></div>
<div>Slide 1</div>
</div>
<div class="swiper-slide">
<div class="slide2 swiper-slide-cover"></div>
<div>Slide 2</div>
</div>
<div class="swiper-slide">
<div class="slide3 swiper-slide-cover"></div>
<div>Slide 3</div>
</div>
<div class="swiper-slide">
<div class="slide4 swiper-slide-cover"></div>
<div>Slide 4></div>
</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
这会向我们报告错误消息:
在这种情况下,问题仅仅是函数声明中省略的下划线:
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
}
}
和
func min <T : Comparable> (_ lhs : Vector2<T>, _ rhs : Vector2<T>) -> Vector2<T> {