Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Нужно ли импортировать неявный метод преобразования в объект-компаньон? Противоречие со Scala для нетерпеливой книги

Автор вопроса: jhegedusОтветов: 2

Приведенный ниже код не работает, но он должен работать в соответствии с книгой "Scala для нетерпеливых" (см. отрывок ниже). Так что я тут не понимаю? Изменились ли правила неявного преобразования в последних версиях Scala (2.8 по сравнению с 2.10)?

РЕДАКТИРОВАТЬ:

Посмотрев на этот вопрос, я понял, что b.hello нужно изменить на (b:A).hello. Это не очень подразумевается. Есть ли способ обойти это?

РЕДАКТИРОВАТЬ 2:

После прочтения еще нескольких этого кажется, что нет другого пути, кроме импорта.

object A {
  implicit def b2a(b:B)=new A
}
class A{
  def hello=println("hello")
}
class B

object ImplicitConversion extends App{
  val b=new B
  b.hello
}

введите здесь описание изображения

  • Это может быть связано с тем, что вам не хватает возвращаемого типа неявного. implicit def b2a(b:B): A =new A flavian 07.03.2014

scalaimplicit-conversion

Ответы

Ответ 1 · рейтинг 3 · Ionuț G. Stan

Это потому, что компилятор Scala не может понять, что вы хотите преобразовать B в A, просто взглянув на этот фрагмент кода:

val b = new B
b.hello // I know the source type is B, but what's the target type?

Рассмотрим случай, когда есть C, похожий на ваш A. Какое из двух преобразований следует выбрать Scala? Слишком много просить Scala искать все другие объекты-компаньоны в системе на предмет возможного неявного преобразования из уже известного исходного типа. И вполне возможно, что это закончится неоднозначным результатом.

Самое простое решение в вашем случае - переместить преобразование B в A из объекта-компаньона A в объект-компаньон B.

class A {
  def hello=println("hello")
}

class B

object B {
  implicit def b2a(b:B)=new A
}

object ImplicitConversion extends App {
  val b=new B
  b.hello
}

Ответ 2 · jhegedus

Решение, предложенное Стэном, удовлетворительно, потому что:

object B  {
  implicit def b2a(b:B)=new A
}

class A{
  def hello=println("hello")
}

class B

class C extends B


object ImplicitConversion extends App{

  val c=new C
  c.hello

}

Здесь мне нужно только включить неявное преобразование b2a в объект-компаньон B.

Затем я могу использовать все подклассы B как A.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы