Неожиданное поведение с последствиями - PullRequest
6 голосов
/ 07 марта 2012

У меня вчера была странная ошибка, которую я в итоге сократил до следующего кода:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class X extends Function[String, Int] { def apply(x: String) = Integer.parseInt(x) }
defined class X

scala> implicit val x = new X
x: X = <function1>

scala> "56" / 2
res2: Int = 28

Я ожидаю, что это вызовет исключение, так как String не имеет / метода.Вместо этого Scala обработал неявную переменную как неявный метод (поскольку он реализует Function[String,Int]) и преобразовал строку «56» в целое число 56.

Как это работает?Основываясь на правилах неявного поиска, я не думал, что будут рассматриваться неявные переменные, которые действуют как функции.

1 Ответ

7 голосов
/ 07 марта 2012

Семантика неявных преобразований - это именно то, что вы наблюдали. Если вы определяете неявное преобразование с помощью неявного метода,

trait A
trait B

implicit def aToB(a : A) : B = new B {}

вы увидите, что теперь у вас есть неявное значение функции A => B,

scala> implicitly[A => B]
res1: A => B = <function1>

А где у вас есть метод с привязкой к представлению,

def foo[T <% B](t : T) : B = t

это эквивалентно,

def foo[T](t : T)(implicit conv : T => B) : B = conv(t)

т. неявный аргумент, соответствующий границе представления, имеет точно такую ​​же форму, что и значение неявной функции, созданное неявным определением метода.

...