2015-07-07 1 views
7

Давайте посмотрим код ниже:Scala неявное преобразование на вызов по имени параметра работает по-разному в зависимости от функции перегружен или не

import scala.language.implicitConversions 
class Foo 
implicit def int2Foo(a: => Int): Foo = new Foo 
def bar(foo: Foo) = {} 
def bar(foo: Boolean) = {} 
bar { 
    println("Hello") 
    64 
} 

Этот код ничего не печатать, потому что блок содержит println("Hello") рассматривается как => Int и преобразуется в Foo по int2Foo. Но удивительно то, произойдет, если мы опустим перегруженная функция bar(foo: Boolean)

import scala.language.implicitConversions 
class Foo 
implicit def int2Foo(a: => Int): Foo = new Foo 
def bar(foo: Foo) = {} 
bar { 
    println("Hello") 
    64 
} 

Печатается Hello, поскольку он оценивает блок, и только последнее утверждение, 64 в данном случае рассматривается в качестве параметра вызова по имени , Я не могу понять, какое обоснование существует за этой разницей.

+1

Связанная проблема: https://issues.scala-lang.org/browse/SI-3237 –

+0

Невозможно, чтобы это поведение предназначалось, если только я чего-то не упускаю. Даже если он соответствует спецификации, он является чрезвычайно противоречивым и серьезно подвержен ошибкам (например, что, если кто-то удаляет перегрузку, которая, по-видимому, используется нигде, что приводит к тому, что параметр by-name ведет себя по-разному). –

+0

Обтекание блока в '{...}: Int' также изменяет поведение. –

ответ

1

Я думаю, что спецификация Scala неоднозначна в отношении того, как здесь должны применяться неявные представления. Другими слова, оба из следующих интерпретаций заявлений соответствуют спецификациям:

bar { println("Hello"); int2Foo(64) } 
bar { int2Foo({ println("Hello"); 64 }) } 

Конечно, это крайне нелогичный для неродственнога от перегрузки влияет на это поведение. Мне кажется, что поведение, хотя и неоднозначное, должно быть, по крайней мере, последовательным. Это должна быть деталь реализации взаимодействия компилятора между разрешением перегрузки, параметрами имени и неявными представлениями. Я зарегистрировал SI-9386 для решения проблемы.

+0

Ничего себе, спасибо за подачу вопроса! – pocorall