Scala eq 问题
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我尝试将
Int
值与整数文字进行比较,并从编译器中得到了一些有趣的注释。这可能会揭示这种行为的原因。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.我认为这是关于 Java 中的类型擦除。当你编译类时,
类型
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
The type
T
will be removed. You can make a test:On the other hand, the
Int
class is a subtype ofAnyVal
, notAnyRef
. Therefore, if you try to apply the methodeq
with an argument1
which is of typeInt
, an runtime error will be emitted.PS: Though
Int
can be convert tojava.lang.Integer
implicitly , as Vilius Normantas pointed out, it can be convert to RichInt implicitly either.