我有许多不同的枚举,例如:
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/