2013-03-19 3 views
6

Я смущен этим описанием в «5.1.3 неявного разрешения» в книге Джошуа Suareth в Scala в глубину, на странице 100:implicits для объектов в Scala

Scala объекты не могут иметь объекты компаньоном для implicits. Из-за это, подразумеваемые, связанные с типом объекта, которые желательны на , неявная область действия этого типа объекта должна быть предоставлена ​​из внешней области . Вот пример:

scala> object Foo { 
    | object Bar { override def toString = "Bar" } 
    | implicit def b : Bar.type = Bar 
    |} 
defined module Foo 
scala> implicitly[Foo.Bar.type] 
res1: Foo.Bar.type = Bar 

Но в то время как я делаю объект Bar заложенным в РЕПЛ:

scala> object Foo { 
    | implicit object Bar { 
    |  override def toString = "isBar" } 
    | } 
defined module Foo 
scala> implicitly[Foo.Bar.type] 
res0: Foo.Bar.type = isBar 

Кажется, что это не нужно определить неявный во внешней области. Или я не считаю смысл Джошуа совершенно неправильным?

+1

Когда была написана книга и какая версия Scala вы используете? Возможно, это немного изменилось в 2.9 или 2.10. – KChaloux

+1

Вещи, как в моем ответе, по крайней мере, от 2.9.x. Джош, должно быть, имел в виду Scala pre-2.9, или просто не знал семантики. FTR Я был удивлен и рад, когда обнаружил, что это возможно. –

+0

Спасибо за ответ. В этой книге предлагается, чтобы он охватывал 2.7.x до 2.9.x. У меня на компьютере установлена ​​2.10, которая может вести себя по-другому. – cfchou

ответ

8

В этом случае объекты действуют как если бы они были их собственные спутники, так что вам просто нужно гнездо вашего объекта-типа упоминая implicits в теле самого объекта,

scala> object Bar { 
    | override def toString = "Bar" 
    | implicit def b : Bar.type = Bar 
    | } 
defined module Bar 

scala> implicitly[Bar.type] 
res0: Bar.type = Bar 

Обратите внимание, что здесь тело Bar был рассмотрен как часть неявного объема для разрешения Bar.type.

Это может показаться неясным углом системы типа Scala, но я смог использовать его в кодировке shapelesspolymorphic (function) values.

2

Если вы поместите следующий код в файл и попытаться скомпилировать с помощью scalac он терпит неудачу с 'implicit' modifier cannot be used for top-level objects

implicit object Foo { 
    object Bar { override def toString = "Bar" } 
} 

Это, однако, отлично компилируется:

object Foo { 
    implicit object Bar { override def toString = "Bar" } 
} 

Я считаю, что с помощью REPLimplicit's являются не совсем верхний уровень, следовательно, кажущаяся несогласованность.

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