2011-01-28 8 views
6

No entiendo por qué el siguiente código no se compila:La omisión de puntos al encadenar llamadas

class Abc 
{ 
    def b (x : String) = x + "abc" 

    def a (y : String) = 
    { 
     val ls : List[String] = y.lines toList 
     b (ls.head) 
    } 
} 

Main.scala: 8: Error: No coinciden los tipos; encontrado: java.lang.String requerido: Int b (ls.head)

Cuando cambio "y.lines toList" para

y.lines.toList 

o incluso a

y.lines toList; 

compila

Tal vez el compilador lo entiende como

(y.lines).toList(b (ls.head)) 

o algo por el estilo, pero todavía no entienden las reglas.

+0

Puede insertar su extracto '(y.lines) .toList (b (ls.head)) ' (¿bueno, tal vez lo hizo?) En el REPL, para verificar que el mensaje de error es el mismo. Bueno, lo hice, y de hecho, lo es. :) –

+0

Es por eso que no me gusta que todo el mundo gime ';'. – Raphael

Respuesta

1

No es obvio, y es una combinación de la sintaxis de acceso directo de Scala y la indexación de la lista. Si quieres un toque, pruebe la redefinición de b a:

def b(x : String) = 0 

que obtendrá alguna otra vuelta compilador de basura, pero el error va a cambiar. En resumen, el compilador de Scala le permitirá omitir los paréntesis y los puntos para métodos de cero o de un parámetro, y sabemos que b parece estar encadenado de algún modo ... El problema es que Scala también usa parens para la indexación de listas, por lo que toList, devuelve un iterador, puede tomar un parámetro como el índice de la lista. No estoy seguro de esta parte exactamente, pero parece que una vez que comienzas a omitir puntos, el lector se vuelve codicioso, y cuando se encuentra con un método que puede tomar un parámetro, intentará pasarle la siguiente declaración. En este caso, es una cadena, por lo que arroja un error de sintaxis.

1

lo tienes en el clavo con esto:

(y.lines).toList(b (ls.head)) 

Con el único ser posible corrección:

(y.lines).toList(b).apply(ls.head) 

No estoy seguro de que Scala decidiría en este caso particular.

La regla, en términos generales, es object (method parameters)* [method]. El compilador continuará mientras encuentre tokens para una expresión válida. Un ; termina la expresión, y también un ) o }. Si la siguiente línea está en blanco, la expresión también finaliza. Si la siguiente línea comienza con una palabra clave reservada (val, def, if, etc.), la expresión también finalizará.

Cuestiones relacionadas