繁体   English   中英

通用枚举函数参数?

[英]Generic Enum Function Parameters?

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

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)的不变式。 由于ab的类型可以不同,因此在大型系统中很容易搞乱。

    • 它很少有意义,并且很少有用。 考虑您的情况: Fruit.apple不等于Wood.oak ,但是您对其进行了切片。 比较是无稽之谈。

斯威夫特的模型更受限制。 如果您查看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)一样使用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM