Scala eq 问题

发布于 2024-10-19 09:51:35 字数 1526 浏览 1 评论 0原文

我在 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[_] = ...;
}

不过,最好使用包装类型。

I am having issues with the following code in 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;
}

I get the following error in compilation

/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] -------------------------

Why doesn't the implicit conversion from Int to Integer handle the issue?

I could easily fix the code by not using eq, but this just doesn't seem right. IMHO the available implicit conversions should be applied here.

UPDATE

I got the issue fixed by using the signature like this

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[_] = ...;
}

Still, it would be good to use the wrapper types instead.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忘东忘西忘不掉你 2024-10-26 09:51:35

我尝试将 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
       ^

I tried comparing an Int value against integer literal and got some interesting note from the compiler. This may shed some light about the causes of this behaviour.

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
       ^
花开柳相依 2024-10-26 09:51:35

我认为这是关于 Java 中的类型擦除。当你编译类时,

class Holder[T] {

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

类型 T 将被删除。您可以进行测试:

在此处输入图像描述"> 另一方面,Int 类是AnyVal 的子类型,而不是 AnyRef。因此,如果您尝试使用类型为 Int 的参数 1 来应用方法 eq,则会发出运行时错误。

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

I think it is about Type Erasure in Java. When you compile the class

class Holder[T] {

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

The type T will be removed. You can make a test:

enter image description here

On the other hand, the Int class is a subtype of AnyVal, not AnyRef. Therefore, if you try to apply the method eq with an argument 1 which is of type Int, an runtime error will be emitted.

PS: Though Int can be convert to java.lang.Integer implicitly , as Vilius Normantas pointed out, it can be convert to RichInt implicitly either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文