Проблемы с Scala eq - PullRequest
       2

Проблемы с Scala eq

3 голосов
/ 28 февраля 2011

У меня проблемы со следующим кодом в 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, но это просто не правильно. ИМХО, здесь должны применяться доступные неявные преобразования.

UPDATE

Я исправил проблему с помощью такой подписи

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 ]

2 голосов
/ 20 марта 2011

Я попытался сравнить значение 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 голос
/ 27 ноября 2011

Я думаю, что это примерно Тип Erasure в Java. Когда вы компилируете класс

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, как отметил Вилиус Нормантас, его можно также преобразовать в RichInt неявно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...