Swift泛型类型推理扩展



我正试图通过为Array类创建Min和Max扩展(类似于C#中的Min和MaxExtension方法)来建立我对Swift中泛型的理解。也许有更好的方法可以做到这一点,但正如我所说,这只是为了帮助我理解泛型。

我已经创建了以下代码:

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

如果有人是这方面的专家,你能告诉我我做错了什么吗?我不得不承认,我花了相当多的阅读和黑客才能走到这一步!

提前感谢任何回复

当您这样定义max(和min)时:

func max<T, U : Comparable>(f: T -> U ) -> U?

实际上,您是在说闭包f可能采用与Array中的元素不同的类型。由于Array已经是一个泛型结构Array<T>,因此可以重用它已经定义的元素类型T。来自Swift语言指南:

扩展泛型类型时,不提供类型参数列表作为扩展定义的一部分。相反,类型原始类型定义中的参数列表在扩展名的主体和原始类型参数名称用于引用原始定义中的类型参数。

因此,由于元素类型T已经对您可用,只需从类型参数列表中取出T,如下所示:

func max<U : Comparable>(f: T -> U ) -> U?

这保证了闭包f将采用与Array中的元素相同的类型T。然后编译器可以正确地推断出您在测试用例中使用的类型,并修复您看到的错误。

最新更新