我试图通过为Array类创建Min和Max扩展来构建我对Swift中Generics的理解(类似于C#中的Min和Max Extension方法)。可能有更好的方法来做到这一点,但正如我所说,它只是为了帮助我理解泛型。
我创建了以下代码:
extension Array {
func max<T, U : Comparable>(f: T -> U ) -> U? {
var maxSoFar : U? = nil
for i in self {
var itemValue = f(i as T)
if(maxSoFar == nil) {
maxSoFar = itemValue
}
if itemValue > maxSoFar {
maxSoFar = itemValue
}
}
return maxSoFar
}
func min<T, U : Comparable>(f: T -> U ) -> U? {
var minSoFar : U? = nil
for i in self {
var itemValue = f(i as T)
if(minSoFar == nil) {
minSoFar = itemValue
}
if itemValue < minSoFar {
minSoFar = itemValue
}
}
return minSoFar
}
}
为了测试,我创建了一个基本的Person类:
class Person {
var name : String
var age : Float
init(name: String, age: Float) {
self.name = name
self.age = age
}
}
当我在闭包中明确表示这似乎适用于这些情况:
var maximumAge = [Person(name: "Bob", age: 42), Person(name:"Mary", age:40)]
.max{ (p: Person) in p.age }! // Gives 42
var min = [100, 101].min{ (i: Int) in i }! // Gives 100
但是,我无法推断出使用极端速记案例的类型:
var maximumAge = [Person(name: "Bob", age: 42), Person(name:"Mary", age:40)]
.max{ $0.age }! // Error
var min = [100, 101].min{ $0 }! // Error
或中等长度:
var maximumAge = [Person(name: "Bob", age: 42), Person(name:"Mary", age:40)]
.max{p in p.age }! // Error
var min = [100, 101].min{ i in i }! // Error
如果有人是这方面的专家,你能告诉我我做错了什么吗?我不得不承认,为了达到这个目的,我花了很多时间阅读和黑客攻击!
提前感谢您的回复
答案 0 :(得分:3)
当您像这样定义max
(和min
)时:
func max<T, U : Comparable>(f: T -> U ) -> U?
你实际上是说封闭f
可能采用与Array
中的元素不同的类型。由于Array
已经是通用结构Array<T>
,因此您可以重复使用已定义的元素类型T
。来自the Swift language guide:
扩展泛型类型时,不提供类型参数 列表作为扩展定义的一部分。相反,类型 原始类型定义中的参数列表可在其中使用 扩展的主体,以及原始类型参数名称 用于引用原始定义中的类型参数。
因此,由于您已经可以使用元素类型T
,只需从类型参数列表中取出T
,如下所示:
func max<U : Comparable>(f: T -> U ) -> U?
这可以保证闭包f
采用与T
中的元素相同的Array
类型。然后,编译器可以正确地推断出您在测试用例中使用的类型,并修复了您看到的错误。