2012-05-03 12 views
12

Il codice riportato di seguito da http://www.scalaclass.com/book/export/html/1 per creare un prodotto a matrice di punti.sintassi del metodo della mappa Scala

Non riesco a capire la sintassi tra parentesi graffe.

  • Perché le parentesi graffe sono utilizzate, non le parentesi del metodo normale?
  • È un metodo anonimo?
  • Che cosa è ._1 e ._2?

Grazie.

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(_ + _) 

risposta

28
  • Perché vengono usate le parentesi graffe, non le parentesi del metodo normale?

Alcune persone preferiscono utilizzare le parentesi graffe quando il parametro è una funzione anonima. Per prima cosa, le parentesi graffe consentono pattern matching funzioni anonime, mentre la parentesi non lo fanno. In questo particolare esempio, non c'è bisogno di parentesi graffe.

Ecco un esempio in cui sono richieste parentesi graffe (a causa della corrispondenza case modello):

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

noti che la funzione sopra compie la stessa cosa come quella in questione, in modo leggermente diverso.

  • È t un metodo anonimo?

No, è un parametro. Proprio come v1 e v2 sono parametri per dotProd, t è un parametro per la funzione anonima passata a map.

  • Ciò che è ._1 e ._2?

Metodi su t. Il parametro t è stata definita come una tupla (in particolare, Tuple2[Double, Double], che può essere scritta come (Double, Double)), e tuple permetterà di estrarre ogni membro della tupla con i metodi del genere: _1, _2, _3, ecc

A Tuple2 ha solo _1 e _2, naturalmente. Si noti che il primo parametro è _1, non _0, a causa dell'influenza di altri linguaggi funzionali.

In ogni caso, il metodo zip convertirà (List[Double]) in un List[(Double, Double)]. Il metodo map accetta una funzione che converte gli elementi della lista (che sono le tuple (Double, Double)) in qualcos'altro.

+0

Sono '._1' e' ._2' veramente metodi di 'Tuple2'? Sapevo che erano campi (come in 'TupleN' avremo i campi' N' da '_1' a' _N', ognuno di qualche tipo 'Ti'. –

+0

@TamoghnaChowdhury Certo, sono metodi. campi attraverso i metodi, a meno che non siano dichiarati come 'private [this]'. –

+0

Oops .Sei assolutamente corretto.Le proprietà trasparenti tendono a confondere le persone usate per gli espliciti accessor/mutator in Java, come me: P. Grazie per avermelo ricordato di nuovo , anche se... –

1

Le parentesi graffe indicano una funzione anonima con tipo Tuple2[Double,Double] => Double. L'argomento ha il nome locale t, quindi t è una tupla di due doppi. t._1 fa riferimento al primo elemento e t._2 il secondo.

Pertanto map produce un elenco di prodotti element-element dei componenti dei due vettori e reduceLeft somma questi prodotti per calcolare il prodotto punto.

+0

Qual è la differenza tra quanto sopra e questo 'Elenco (1,2,3) .map (x => x + 1)' – Nabegh

+0

@Nabegh in questo caso, non c'è differenza. –

12

In questo caso particolare parentesi graffe non hanno alcun vantaggio rispetto vecchia sintassi semplice, ma in generale la cosa dolce sull'utilizzo di parentesi graffe è che essi consentono di scrivere modello corrispondenti espressioni all'interno map ...:

così posso riscrivere questo

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

in questo

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

ma questo non compilerà:

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

._1, ._2 fornisce l'accesso al primo, secondo, ... N elemento di N-tupla, come ha detto Lee.

+0

E non è possibile avere più di un parametro tra parentesi graffe. –

5

Si può trovare una risposta molto buona per le differenze tra parentesi graffe {} e parentesi() in questa domanda: What is the formal difference in Scala between braces and parentheses, and when should they be used?

Per la _1, _2, vedi Meaning of _2 sign in scala language.

E sì, t:(Double, Double) => t._1 * t._2 è una funzione anonima (non un metodo in realtà). Difference between method and function in Scala

+1

Err, 't' è un parametro, non una funzione anonima. –

+0

@ DanielC.Sobral Sì, certo che hai ragione, voglio dire che l'intero costrutto è una funzione anonima. –