2012-05-03 12 views
12

El código siguiente a partir de http://www.scalaclass.com/book/export/html/1 para hacer el producto matriz de puntos.Sintaxis del método de mapa de Scala

No puedo entender la sintaxis entre los corchetes.

  • ¿Por qué se usan las llaves, no el método habitual entre paréntesis?
  • ¿Es un método anónimo?
  • ¿Qué es ._1 y ._2?

Gracias.

type Row = List[Double] 
type Matrix = List[Row] 

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _) 

Respuesta

28
  • ¿Por qué se utilizan las llaves, no el método habitual entre paréntesis?

Algunas personas prefieren usar llaves cuando el parámetro es una función anónima. Por un lado, las llaves permiten que el patrón coincida con las funciones anónimas, mientras que los paréntesis no lo hacen. En este ejemplo particular, no hay necesidad de llaves.

He aquí un ejemplo en el que se requieren llaves (debido a la coincidencia de case patrón):

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _) 

Tenga en cuenta que la función anterior logra el mismo que el de la pregunta, de una manera ligeramente diferente.

  • ¿Es t un método anónimo?

No, es un parámetro. Al igual que v1 y v2 son parámetros para dotProd, t es un parámetro para la función anónima que se pasa al map.

  • ¿Qué es ._1 y ._2?

Métodos en t. El parámetro t se definió como una tupla (específicamente, Tuple2[Double, Double], que puede ser escrita como (Double, Double)), y tuplas le permiten extraer cada miembro de la tupla con métodos como que: _1, _2, _3, etc.

A Tuple2 solo tiene _1 y _2, por supuesto. Tenga en cuenta que el primer parámetro es _1, no _0, debido a la influencia de otros lenguajes funcionales.

De todos modos, el método zip convertirá (List[Double]) en un List[(Double, Double)]. El método map toma una función que convierte los elementos de la lista (que son (Double, Double) tuplas) en algo más.

+0

¿Son '._1' y' ._2' realmente los métodos de 'Tuple2'? Sabía que eran campos (como en 'TupleN' tendrá' N' campos de '_1' a' _N', cada ser de algún tipo 'Ti'. –

+0

@TamoghnaChowdhury Claro, son métodos. Acceso a Scala prácticamente todo campos a través de métodos, a menos que estén declarados como 'privados [esto]'. –

+0

¡Uy! Está absolutamente correcto. Las propiedades transparentes tienden a confundir a las personas utilizadas para acceder/modificadores explícitos en Java, como yo: P. Gracias por recordarme otra vez , aunque... –

1

Los corchetes denotan una función anónima que tiene el tipo Tuple2[Double,Double] => Double. El argumento recibe el nombre local t, por lo que t es una tupla de dos dobles. t._1 se refiere al primer artículo y t._2 el segundo.

Por lo tanto map produce una lista de los productos elemento racional de los componentes de los dos vectores, y reduceLeft sumas estos productos para calcular el producto escalar.

+0

Cuál es la diferencia entre lo anterior y esta 'Lista (1,2,3) .map (x => x + 1)' – Nabegh

+0

@Nabegh en este caso, no hay diferencia. –

12

En este caso particular entre llaves tienen ninguna ventaja sobre la sintaxis simple y llano, pero en general el dulce cosa sobre el uso de llaves es que le permiten escribir expresiones de coincidencia de patrones dentro map ...:

para que pueda volver a escribir este

.map{ t:(Double, Double) => t._1 * t._2 } 

en este

.map{ case(a: Double, b: Double) => a*b } 

pero esto no se compilará:

.map(case(a: Double, b: Double) => a*b) 

._1, ._2 proporciona acceso al primer, segundo, ... N elemento de N-tupla, como dijo Lee.

+0

Y no puede tener más de un parámetro dentro de llaves. –

5

puede encontrar una muy buena respuesta a las diferencias entre llaves {} y paréntesis() en esta pregunta: What is the formal difference in Scala between braces and parentheses, and when should they be used?

Para el _1, _2, ver Meaning of _2 sign in scala language.

Y sí, t:(Double, Double) => t._1 * t._2 es una función anónima (no es un método en realidad). Difference between method and function in Scala

+1

Err, 't' es un parámetro, no una función anónima. –

+0

@ DanielC.Sobral Sí, por supuesto tienes razón, quiero decir que todo el constructo es una función anónima. –

Cuestiones relacionadas