12.3. Konflikty nazw

Nazwy obiektów i pakietów w języku Scala należą do tej samej przestrzeni nazw, co może prowadzić do konfliktów nazw. W pliku PackageNameConflicts1.scala zdefiniowana jest metoda speak, znajdująca się w obiekcie hello, w pakiecie greetings.

Plik PackageNameConflict1.scala:
package greetings {
  object hello {
    def speak = println("Hello!")
  }
}

Do metody speak można się odwołać za pomocą wyrażenia greetings.hello.speak.

scala> greetings.hello.speak
Hello!

W pliku PackageNameConflict2.scala zdefiniowano metodę speak w obiekcie pakietowym hello, który z kolei znajduje się w pakiecie greetings.

Plik PackageNameConflict2.scala:
package greetings {
  package object hello {
    def speak = println("Hello!!")
  }
}

Do tej metody speak można się odwołać tak jak do poprzedniej.

scala> greetings.hello.speak
Hello!!

W pliku PackageNameConflict3.scala, w pakiecie greetings.hello zdefiniowany jest obiekt speak.

Plik PackageNameConflict3.scala:
package greetings {
  package hello {
    object speak {
      println("Hello!!!")
    }
  }
}

Do tego obiektu można się odwołać w sposób podobny do odwołań do wcześniej pokazanych metod speak.

scala> greetings.hello.speak
Hello!!!
res0: greetings.hello.speak.type = greetings.hello.speak$@1b3d178

Można sobie zadać pytanie co się stanie, jeśli spróbujemy połączyć powyższe definicje w jednym programie. W pliku PackageNameConflict12.scala znajduje się program próbujący połączyć pierwszą i drugą.

Plik PackageNameConflict12.scala:
package greetings {
  object hello {
    def speak = println("Hello!")
  }
  package object hello {
    def speak = println("Hello!!")
  }
}

Taki program nie kompiluje się.

$ scalac PackageNameConflict12.scala
PackageNameConflict12.scala:5: error: hello is already defined as object hello
  package object hello {
                 ^
one error found

W pliku PackageNameConflict13.scala przedstawiona jest próba połączenia pierwszej definicji z trzecią.

Plik PackageNameConflict13.scala:
package greetings {
  object hello {
    def speak = println("Hello!")
  }
  package hello {
    object speak {
      println("Hello!!!")
    }
  }
}

Ten plik również nie kompiluje się.

$ scalac PackageNameConflict13.scala
PackageNameConflict13.scala:5: error: hello is already defined as object hello
  package hello {
          ^
one error found

W pliku PackageNameConflict23.scala przedstawiona jest próba połączenia drugiej definicji z trzecią.

Plik PackageNameConflict23.scala:
package greetings {
  package object hello {
    def speak = println("Hello!!")
  }
  package hello {
    object speak {
      println("Hello!!!")
    }
  }
}

Tym razem kompilacja udaje się.

$ scalac PackageNameConflict23.scala

$

Program z pliku PackageNameConflict23.scala definiuje obiekt speak i metodę speak. Obie należą do tego samego pakietu greetings.hello, przy czym obiekt speak jest zdefiniowany w pakiecie, a metoda greet w obiekcie pakietowym. Takich sytuacji należy unikać. Według specyfikacji języka (punkt 9.3 w specyfikacji), w definicji obiektu pakietowego nie należy definiować składowych o takiej samej nazwie, jak jeden z obiektów lub jedna z klas należących do pakietu. Zachowanie programu, w przypadku konfliktu nazw, jest niezdefiniowane.

Język programowania Scala Wydanie 2. Copyright © Grzegorz Balcerek 2016

Licencja Creative Commons

Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowe.

Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.