3

我试图通过为 Array 类创建 Min 和 Max 扩展(类似于 C# 中的 Min 和 Max Extension 方法)来建立我对 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

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

提前感谢您的任何回复

4

1 回答 1

3

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

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

您实际上是在说闭包f可能采用与Array. 由于Array已经是一个通用的 struct Array<T>,您可以重新使用T它已经定义的元素类型。来自Swift 语言指南

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

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

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

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

于 2014-09-30T18:25:39.777 回答