Swift 泛型类型推断扩展

标签 swift generics swift-extensions

我试图通过为 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

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

提前感谢任何回复

最佳答案

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

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

您实际上是在说闭包 f可能采用与 Array 中元素不同的类型.自 Array已经是通用结构 Array<T> ,您可以重新使用元素类型 T它已经被定义了。来自 the Swift language guide :

When you extend a generic type, you do not provide a type parameter list as part of the extension’s definition. Instead, the type parameter list from the original type definition is available within the body of the extension, and the original type parameter names are used to refer to the type parameters from the original definition.

因此,由于元素类型为 T您已经可以使用了,只需输入 T在类型参数列表之外,像这样:

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

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

关于Swift 泛型类型推断扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26126625/

相关文章:

PowerShell 2 中的泛型不起作用?

ios - 我很困惑类扩展中声明的任何方法是否是静态的

ios - 不能在子类中运行 SKAction.runBlock

ios - 在 Swift 中从另一个 View Controller 呈现子类 View Controller

reference - Swift 中的异常行为 : constant defined with LET but behaving like a variable defined with VAR

objective-c - Cocoapods 框架中的 Swift 扩展导致无法识别的选择器发送到类

swift - 如何使用私有(private)集扩展协议(protocol)?

Swift,基于扩展协议(protocol)的类不符合原始协议(protocol)

c# - 如何在 C# 中创建 UserControl<T>?

java - 避免在泛型层次结构中进行强制转换