Questo non funziona come previsto (dal momento che sto cercando di chiamare un pacchetto privato run
dall'esterno Services
):Scala: pacchetto Accesso metodi visibili attraverso tipologie strutturali al di fuori del pacchetto
object Services {
class HelloPrinter {
private[Services] def run = "Hello"
}
}
val obj = new Services.HelloPrinter
Ma, sorprendentemente questo funziona:
val obj: {def run: String} = new Services.HelloPrinter
obj.run
direi, è un bug nel compilatore poiché come HelloPrinter non corrisponde al tipo strutturale a causa delle regole pacchetto di visibilità, non dovrebbe compilare a tutti!
Ecco un caso in cui il programma viene compilato, ma genera un'eccezione di runtime (java.lang.NoSuchMethodException
):
class HelloPrinter {
private[HelloPrinter] def run = "Hello"
}
val obj: {def run: String} = new HelloPrinter
obj.run
Si tratta di una caratteristica del linguaggio o di regola mi manca o legittimamente un bug in Scala?
Molto interessante. Hai provato a girare con REPL di scala? Mostra chiaramente che c'è una chiamata riflessiva invocata. Immagino che l'ambito e l'immutabilità siano tutti fuori dalla finestra quando si parla di riflessione. – marios
Beh, per quanto posso dire, l'avvertimento è più inteso a renderti cauto sulle possibili conseguenze delle prestazioni. La mia comprensione è che, nonostante l'uso della reflection per eseguire l'effettiva chiamata in fase di esecuzione, la tipizzazione strutturale è (presumibilmente) tipizzata staticamente come qualsiasi altra cosa in scala, perché il compilatore verificherà che le firme corrispondano rigorosamente (e quindi la chiamata riflessiva può solo avere successo). A meno che, naturalmente, non si esegua un downcast esplicito a un tipo strutturale. Comunque qui non c'è cast, il compilatore sembra semplicemente omettere di verificare la visibilità del metodo. –
Il secondo esempio che tu dici di non eseguire una 'NoSuchMethodException' per me (nel REPL 2.10.4 e 2.11.6). –