swift - 通用枚举函数参数?

标签 swift generics enums

我有许多不同的枚举,例如:

enum Fruit {
    case apple, pear, banana, melon
}

enum Wood {
    case oak, birch, mahogany
}

我想编写一个静态函数来比较两个指定的通用枚举值是否相同。

funct myCmp<T>(a: T, b: T) -> Bool {
    return a == b // cannot compare generic types
}

如何做到这一点?在 Java 中,这很容易完成,无需任何额外的代码,这就是我感到困惑的原因。

最佳答案

Java 对平等有更广泛的定义。任何两个对象都可以进行比较。这有明显的好处,但也有很多复杂性和缺点。例如:

  • 大多数对象仅与同一类的对象进行同等比较,因此您最终会在 equals() 的每个实现中重复大量样板文件。 ,例如:

    @Override
    public boolean equals(Object o) {
        // self check
        if (this == o)
            return true;
        // null check
        if (o == null)
            return false;
        // type check and cast
        if (getClass() != o.getClass())
            return false;
        Person person = (Person) o;
    
        // ACTUAL comparison starts here.
    }
    
  • 引入微妙但非常令人困惑的错误确实很容易,这些错误源于 equals 的意外不对称实现。 。您必须确保 Equals 的每次实现满足 a.equals(b) == b.equals(a) 的不变量。由于 a 的类型和b可能会有所不同,这在大型系统中很容易搞砸。

    • 它很少有意义,也很少有用。考虑您的情况:Fruit.apple不等于Wood.oak ,无论你如何切片它。这种比较毫无意义。

Swift 的模型更加锁定。如果你看Equatable ,它规定两个参数的类型均为 Self 。上面 Java 代码中的三个检查中的两个(参数不为 null,并且其类型匹配)不是必需的,因为实际上不可能说服类型系统提供 nil或错误地输入对象作为 == 的参数.

<小时/>

后来完全误解了:

可以编写一个函数来比较(单个)泛型类型的任何对象 T ,但是您缺少的是一个常量 T是可以平等的。不知不觉T是相等的,你的函数不能确定合适的 ==甚至存在。

这是您的示例:

func myCmp<T: Equatable>(a: T, b: T) -> Bool {
    return a == b
}

对于您评论中更具体的示例,我将在 Sequence 上使用扩展名,而不是函数:

extension Collection where Element: Equatable {
    func allEqual(to desiredElement: Element) -> Bool {
        for element in self {
            if element != desiredElement { return false }
        }
        return true
    }
}

并像[fruitA, fruitB, fruitC].allEqual(to: .apple)一样使用它

关于swift - 通用枚举函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57881540/

相关文章:

ios - 如何使两次不同的碰撞产生不同的结果?

swift - 带有自定义对象的 setObjectForKey 方法在 NSUserDefaults swift 中不起作用

java - 使用通过反射获得的枚举常量

generics - Kotlin 外投影类型禁止使用

java - 如何在 Java 的枚举中保存图像?

c# - 使用 CType 的枚举解决重载问题

ios - Swift inout 参数性能

ios - '无法将类型 'Int' 的值转换为预期参数类型 'CGPoint'

java - 如何从另一个泛型类参数转换泛型参数?

Swift (4) 无法转换为泛型基类?