2009-06-17 8 views
22

In Scala, perché è possibile omettere il punto e le parentesi in T m 0 (anziché T.m(0)) nel modo seguente?Quali caratteri posso omettere in Scala?

scala> object T { def m(i:Int) = 0 == i } 
defined module T 

scala> T m 0 
res19: Boolean = true 

Ma perché non posso omettere le parentesi nel n(0) nel seguente?

scala> def n(i:Int) = 0 == i 
n: (Int)Boolean 

scala> n 0 
<console>:1: error: ';' expected but integer literal found. 
     n 0 
     ^

risposta

36

L'esempio precedente, T m 0, è un esempio di "notazione dell'operatore". Scala ha tre tipi di notazioni operatore, prefisso (chiamato unario), infisso e suffisso. Vediamo alcuni esempi di tutti e tre in azione qui:

class MyByte(val n : Int) { 
    require(n >= 0 && n <= 255) 
    def unary_! = new MyByte(n^0xff) 
    def +(m : MyByte) = new MyByte(n + m.n) 
    def bits = (math.log(n)/math.log(2) + 1).toInt 
    override def toString = "0" * (8 - bits) + n.toBinaryString 
} 

Una qui è in uso:

scala> val a = new MyByte(5) 
a: MyByte = 00000101 

scala> val b = new MyByte(10) 
b: MyByte = 00001010 

scala> ! a // Prefix/Unary 
res58: MyByte = 11111010 

scala> a + b // Infix 
res59: MyByte = 00001111 

scala> b bits // Postfix 
res60: Int = 4 

Mentre infissa e Postfix notazioni accettano qualsiasi identificatore Scala valida, anche se si parla di limitare la notazione postfix , solo quattro identificatori possono essere usati come prefisso: ~,!, - e +.

Ora, quando si prova "m 0", Scala lo ignora essendo un operatore unario, in quanto non valido (~,!, - e +). Trova che "m" è un oggetto valido: è una funzione, non un metodo, e tutte le funzioni sono oggetti.

Poiché "0" non è un identificatore Scala valido, non può essere né un operatore infisso né un operatore postfisso. Pertanto, Scala si lamenta che si aspettava ";" - che separerebbe due espressioni (quasi) valide: "m" e "0". Se lo hai inserito, allora si lamenterebbe che m richiede un argomento o, in mancanza, un "_" per trasformarlo in una funzione parzialmente applicata.

+0

Le liste non usano ::: e :: come notazione prefisso? – andychase

+1

@ asperous.us No. Gli operatori che terminano in ':' hanno una diversa [fissità] (http://en.wikipedia.org/wiki/Operator_associativity): sono _right associative_ invece di _left associative_, ma sono operatori infissi lo stesso. –

3

Credo che lo stile di sintassi dell'operatore funzioni solo quando hai un oggetto esplicito sul lato sinistro. La sintassi è concepita per consentire di esprimere operazioni di stile "operando con operatore operando" in modo naturale.

+1

Non so cosa intendi per oggetto esplicito, ma puoi avere praticamente tutto ciò che valuta un oggetto sul lato sinistro, giusto? (... sinistra?) –

Problemi correlati