to nie działa zgodnie z oczekiwaniami (od Próbuję zadzwonić pakiet prywatnej run
z zewnątrz Services
):Scala: Pakiety Dostęp widoczne metody poprzez typów strukturalnych poza pakietem
object Services {
class HelloPrinter {
private[Services] def run = "Hello"
}
}
val obj = new Services.HelloPrinter
Ale, o dziwo to działa:
val obj: {def run: String} = new Services.HelloPrinter
obj.run
chciałbym powiedzieć, jest to błąd w kompilatorze ponieważ jak HelloPrinter nie pasuje do typu strukturalnego z powodu zasad widoczności pakiet, to nie powinien skompilować w ogóle!
Oto przypadek, w którym program kompiluje ale zgłasza wyjątek środowiska wykonawczego (java.lang.NoSuchMethodException
):
class HelloPrinter {
private[HelloPrinter] def run = "Hello"
}
val obj: {def run: String} = new HelloPrinter
obj.run
czy jest to cecha języka lub orzekania jestem brakujące lub legalnie błąd w Scala?
Bardzo interesujące. Czy próbowałeś uruchomić z 'scala -feature' REPL? Wyraźnie widać, że istnieje odwołanie odblaskowe. Przypuszczam, że zakres i niezmienność są nie na miejscu, jeśli chodzi o refleksję. – marios
No cóż, o ile mogę powiedzieć, ostrzeżenie ma na celu uczynienie cię ostrożnym przed możliwymi konsekwencjami wydajności. Rozumiem, że pomimo użycia refleksji do wykonania faktycznego wywołania w czasie wykonywania, strukturalne pisanie jest (rzekomo) tak statycznie wpisane, jak cokolwiek innego w scala, ponieważ kompilator sprawdzi, czy podpisy ściśle się zgadzają (a zatem tylko odblaskowe wywołanie może osiągnąć sukces). O ile oczywiście nie wykonasz wyraźnego downcastu do typu strukturalnego. Jednak tutaj nie ma obsady, kompilator po prostu wydaje się pomijać sprawdzanie widoczności metody. –
Drugi przykład, który powiedziałeś, rzuca 'NoSuchMethodException', nie kompiluje się dla mnie (w REPL 2.10.4 i 2.11.6). –