Scala eq问题

时间:2011-02-28 09:08:12

标签: scala

我在Scala中遇到以下代码问题

import org.junit.Test
import org.junit.Assert._

class BoxingTest {

    val holder: Holder[Integer] = new Holder[Integer]();

    @Test
    def Holder_Eq_Primitive(){        
        assertEquals(holder, holder eq 1);
    }

    @Test
    def Holder_Eq_Boxed(){        
        assertEquals(holder, holder eq 1.asInstanceOf[Integer]);
    }

}

class Holder[T] {

    def eq(other: T): Holder[_] = this;
}

我在编译中遇到以下错误

/BoxingTest.scala:12: error: type mismatch;
[INFO]  found   : Int
[INFO]  required: AnyRef
[INFO] Note: primitive types are not implicitly converted to AnyRef.
[INFO] You can safely force boxing by casting x.asInstanceOf[AnyRef].
[INFO]         assertEquals(holder, holder eq 1);
[INFO]                                     ^
[ERROR] one error found
[INFO] -------------------------

为什么从Int到Integer的隐式转换没有处理问题?

我可以通过不使用eq轻松修复代码,但这似乎不对。恕我直言,应在此处应用可用的隐式转换。

更新

我通过使用像这样的签名来解决问题

import org.junit.Test
import org.junit.Assert._

class BoxingTest {

    @Test
    def Holder_Eq_Primitive(){
        val holder: Holder[Int] = new Holder[Int]();
        assertEquals(holder, holder eq 1);
    }

    @Test
    def Holder_Eq_Boxed(){
        val holder: Holder[Integer] = new Holder[Integer]();
        assertEquals(holder, holder eq 1.asInstanceOf[Integer]);
    }

}

class Holder[T] {

    def eq(other: T): Holder[_] = ...;
}

但是,最好使用包装类型。

2 个答案:

答案 0 :(得分:2)

我尝试将Int值与整数文字进行比较,并从编译器中获得了一些有趣的注释。这可能会解释这种行为的原因。

scala> val a = 1
scala> a eq 1
<console>:6: error: type mismatch;
 found   : Int
 required: ?{val eq: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method int2Integer in object Predef of type (Int)java.lang.Integer
 and method intWrapper in object Predef of type (Int)scala.runtime.RichInt
 are possible conversion functions from Int to ?{val eq: ?}
       a eq 1
       ^

答案 1 :(得分:1)

我认为它与Java中的 Type Erasure 有关。编译类时

class Holder[T] {

    def eq(other: T): Holder[_] = this;
}

将删除T类型。你可以做一个测试:

enter image description here

另一方面,Int类是AnyVal的子类型,而不是AnyRef。因此,如果您尝试将方法eq应用于类型为1的参数Int,则会发出运行时错误。

PS:虽然Int可以隐式转换为java.lang.Integer,但正如Vilius Normantas指出的那样,它也可以隐式转换为RichInt。