Interpolatore a stringa di Scala: funzione ad-hoc del costrutto generale?

1

In Scala 2.10 è stata aggiunta una nuova funzione interpolatore (vedi qui ).

Ad esempio

val name = "James"
println(s"Hello, $name") // Hello, James

Ciò che non mi è chiaro è se questa funzione è un'aggiunta ad-hoc o se è zucchero sintattico per qualche altro costrutto più generale.

L'unica cosa che posso pensare è che il compilatore trasforma una stringa letterale come

s"Hello, $name"

in un'espressione come

"Hello, " + name

ma ancora, questo mi sembra un trattamento molto speciale di stringhe letterali (vedi anche la domanda relativa su XML letterali ). O è questa una particolare applicazione di qualche più generale costrutto di Scala?

Modifica

Grazie per il feedback. Avevo letto l'intero articolo ma probabilmente il mio riassunto non era abbastanza accurato, rendendo poco chiaro il punto della mia domanda. Grazie a Jörg per il buon sommario.

Ciò che mi lascia perplesso è che il compilatore espande uno speciale letterale stringa in un'espressione che contiene nomi definiti all'interno della stringa stessa. L'espressione risultante deve essere ricompilata per verificare che i nomi degli argomenti utilizzati per chiamare l'istanza StringContext siano definiti nello scope lessicale corrente.

Questa mi sembra una specie di pre-elaborazione (prima passa: espansione letterale speciale, seconda passata: compilazione) perché il valore del token s"Hello, $name" è pre-elaborato ed espanso in un intero sotto-albero dell'albero della sintassi .

Questa espansione è integrata nel compilatore: per quanto ne so, non può essere definita in termini del linguaggio stesso per mezzo di caratteristiche più primitive che prendono la stringa letterale così com'è come input perché i nomi definiti all'interno della stringa devono essere estratti e interpretati come variabili dall'ambito lessicale.

Ad esempio, (per quanto ho capito) nessun metodo Scala può essere chiamato con la stringa "Hello, $ name" e scoprire che c'è una variabile name nello scope lessicale dell'espressione in cui il metodo ha stato chiamato Pertanto, è il compilatore che deve scrivere

StringContext("Hello ").s(name)

e quindi ricompilare il risultato, verificare che la variabile name esista e generare una chiamata al metodo corretta.

Riassumendo, trovo questo riferimento a una variabile nello scope lessicale all'interno di una stringa letterale molto strana, sembra che qualcosa stia accadendo su un diverso livello del linguaggio. Non so come spiegarlo in un modo migliore.

    
posta Giorgio 24.05.2013 - 22:21
fonte

1 risposta

3

La traduzione è spiegata nell'articolo che hai collegato a:

foo"bar"

è tradotto in

StringContext("bar").foo

e

foo"bar $baz quux $frob blurb"

è tradotto in

StringContext("bar ", " quux ", " blurb").foo(baz, frob)

Puoi aggiungere i tuoi metodi a StringContext usando il pattern di pimp-my-library.

Sì, questo è un trattamento speciale per le stringhe letterali. Non esiste una funzionalità simile per i valori letterali numerici. Tuttavia, il tuo metodo può essere arbitrariamente complesso e persino contenere un parser completo, quindi puoi creare la tua notazione numerica per i numeri. Per esempio:.

implicit class RomanNumerals(val sc: StringContext) extends AnyVal {
  def roman() = if (sc.parts(0) == "V") 5 else 10 // Stub implementation
}

val n = roman"X"
// n: Int = 10

Come puoi vedere, il tipo di ritorno del tuo metodo di interpolazione della stringa non deve essere un String . In altre parole: il risultato dell'interpolazione di una stringa non deve essere una stringa.

    
risposta data 25.05.2013 - 00:05
fonte

Leggi altre domande sui tag