Почему члены моего вложенного сопутствующего объекта автоматически не видны в классе? - PullRequest
8 голосов
/ 25 ноября 2010

Предположим, у меня есть этот код Scala:

object Outer {

  object Inner {
    val B = "B"
  }
  class Inner {
    def b = B
  }
}

Я ожидаю, что это скомпилируется, но к B нельзя получить доступ из определения b. Мне нужно добавить import Inner._ в class Inner, чтобы все заработало. Это почему? Правильно ли определен объект-компаньон Inner?

Ответы [ 2 ]

11 голосов
/ 25 ноября 2010

Если члены объекта-компаньона будут импортированы в класс, это приведет к загрязнению пространства имен класса без возможности его управления программистом. Это может быть не так уж плохо (но все же плохо) со значениями, но я действительно не хотел бы видеть это с функциями.

Просто подумайте о apply() или функциях, которые вы наследуете от черт (в обоих случаях вы не можете просто изменить имя, не потеряв чего-либо). Если эти функции автоматически импортируются в пространство имен ваших классов, компилятор не будет знать, какую из них использовать. Поэтому, если бы у класса и объекта была функция func(), вы бы в итоге написали this.func() в своем коде классов просто для того, чтобы убедиться, какой из них вызвать.

Так что рассматривайте это как возможность поддерживать чистоту вашего пространства имен. Вы все еще можете загрязнить его, используя import Inner._

6 голосов
/ 25 ноября 2010

Это просто не должно работать таким образом - использование import Inner._ является непротиворечивым поведением.


Как правило, объект-компаньон необходим, если вы хотите добиться поведения, подобного статическим членам в Java,Способ Scala состоит в том, чтобы переместить все статические элементы в одноэлементный объект с тем преимуществом, что из него можно получить доступ к закрытым / защищенным членам класса-компаньона:

object Outer {

  object Inner {
    def print(inner: Inner) = inner.B // compiles!
  }    
  class Inner {
    private val B = "B"
  }    
}

Вы можете использовать объект-компаньон в качестве фабрики длякласс с приватным конструктором:

scala> object Outer {
     |
     |   object Inner {
     |     def newInstance = new Inner()
     |   }
     |   class Inner private() {
     |     private val B = "B"
     |   }
     | }
defined module Outer

scala> Outer.Inner.newInstance
res1: Outer.Inner = Outer$Inner@431693

scala> new Outer.Inner
<console>:7: error: constructor Inner cannot be accessed in object $iw
       new Outer.Inner
       ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...