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.
Plik PackageNameConflict1.scala:
package greetings {
object hello {
def speak = println("Hello!")
}
}
