2013-07-02 2 views
6

Вот короткий код:Scala: применение зрения

import scala.language.implicitConversions 

implicit def str2int(str:String) = str.toInt 

object Container { 
    def addIt[A](x: A)(implicit str2int: A => Int) = 123 + x 
    def addIt2(x: String)(implicit str2int: String => Int) = 123 + x 
} 

println(Container.addIt("123")); 
println(Container.addIt2("123")); 

Два вопроса:

  1. является "(неявный str2int: A => Int)" называется вид? Когда вы говорите «представление», которое указывает конкретная часть кода?
  2. Почему addIt возвращает 246, в то время как addIt2 возвращает строку «123123»?

Любой хороший ресурс на эту тему также был бы признателен. Спасибо.

ответ

4

Вид означает, что тип A может быть «просмотрен» как тип B, указанный неявной функцией A => B. Итак, да, оба неявных аргумента в addIt и addIt2 - это виды.

addIt2 возвращается 123123, потому что это (к сожалению) можно назвать + на двух объектах, где один из них является String. Это происходит до того, как Scala рассмотрит возможность применения преобразования str2int. Если вы не хотите этого, вы можете явно применить вид:

def addIt2(x: String)(implicit str2int: String => Int) = 123 + str2int(x) 

Или вы можете скрыть any2stringadd преобразование:

object Container { 
    import Predef.{any2stringadd => _} 
    def addIt2(x: String)(implicit str2int: String => Int) = 123 + x 
} 
2
  1. Да это неявный вид, но это Безразлично 't указывает какую-либо конкретную часть кода. Он просто говорит, что тип A должен быть «конвертируемым», предпочтительно неявным, для типа Int, например. неявный конвертер должен находиться в области действия при вызове этого метода.

  2. Похоже, когда компилятор переводит первый метод, он видит 123. + (X: A) и пытается найти неявный тип A, который будет компилировать '+'.

Во втором случае, однако, он видит 123 + (х: String). И есть такое неявное преобразование в Scala Predef. Это на самом деле причуда в реализации Scala. Неявная декларация:

final class StringAdd(self: Any) { 
    def +(other: String) = self.toString + other 
} 

Он был оставлен в Скале для удобства бывших разработчиков Java, которые используются для синтаксиса как: 123 + "something" и ожидает, что это будет строкой.

Смежные вопросы