Kotlin:prevent==编译时使用了错误的类型 让我们考虑下面的简化例子: interface I { /* some stuff */ } object A: I { /* some stuff */ } object B: I { /* some more stuff */ } class Cell<J: I>(val n: Int, val j: J) { /* some more stuff that uses j */ fun eq(c: Cell<J>): Boolean { return n == c.n } }

Kotlin:prevent==编译时使用了错误的类型 让我们考虑下面的简化例子: interface I { /* some stuff */ } object A: I { /* some stuff */ } object B: I { /* some more stuff */ } class Cell<J: I>(val n: Int, val j: J) { /* some more stuff that uses j */ fun eq(c: Cell<J>): Boolean { return n == c.n } },kotlin,Kotlin,这样做的缺点是单元(1,A)=单元(2,B)将愉快地编译。当然,我可以在运行时检查j是否相同,但我想在运行程序之前知道它。我能做什么?您目前拥有的是解决方案equals没有任何类型安全性 使用类型安全性,您将无法正确比较不同抽象上的类型,除非您首先指定了更高层次的类型: class Sub : Super class Super(val num: Int) fun compare(sub: Sub, super: Super) { val superFirst = super == s

这样做的缺点是
单元(1,A)=单元(2,B)
将愉快地编译。当然,我可以在运行时检查j是否相同,但我想在运行程序之前知道它。我能做什么?

您目前拥有的是解决方案
equals
没有任何类型安全性

使用类型安全性,您将无法正确比较不同抽象上的类型,除非您首先指定了更高层次的类型:

class Sub : Super
class Super(val num: Int)

fun compare(sub: Sub, super: Super) {
    val superFirst = super == sub // would compile
    val subFirst = sub == super // wouldn't compile
}
因此,
equals
指定严格的参数是没有意义的

equals
函数的参数为
Any
,因此您永远不会从该函数收到类型安全性。您也不能重载运算符,因为尝试这样做会引发错误


equals
唯一的目的是在运行时检查相等性(通过潜在的类型检查和状态检查),因此它不是用于此目的的合适工具

我在寻找类似于==在Haskell中的工作方式的东西

即使您不需要将其命名为
==
,这也不能很好地与JVM子类型进行互操作,Kotlin需要支持JVM子类型(Haskell当然不支持)。查看失败的尝试可能会有所启发:

public infix fun <A> A.eq(x: A) = this == x
public infix fun A.eq(x:A)=this==x
这要求接收方和参数具有相同的类型
A
,因此
1eq”“
不应该编译,对吗?错了!编译器“有益地”推断出
A
Any
,这在Haskell中是做不到的

另一个问题:能否比较
Interface1
Interface2
类型的值?它们可以是相等的,因为它们都可以属于实现这两个接口的类


实际上,您可以在Scala中执行此操作,因为类型推断在那里的工作方式不同,但我认为Kotlin不存在一个好的解决方案。

“它不是适合此操作的合适工具”,那么合适的工具是什么?我在寻找类似于Haskell中的
=
工作原理的东西。@zabolekar您拥有的工具将是合适的工具。Kotlin的目标不是解决现有解决方案可以轻松解决的问题。例如,正如开发人员所提到的,许多人都要求使用三元运算符,但由于
if
是一个表达式而拒绝使用该运算符—降低冗余度不是Kotlin的目标。类型安全的equals并没有被广泛化到实际需要的程度,特别是当它与我在文章中提到的问题捆绑在一起时。因此,您不能使用
==
而期望类型安全。这个特定的问题可以解决,但还有其他问题。
public infix fun <A> A.eq(x: A) = this == x