2015-02-06 13 views
5

Non sono un esperto di Scala e sono confuso dalla sintassi di chiamare un metodo con un parametro implicito.Differenze in "prose" e "notazione punto" quando si richiama un metodo con parametri impliciti (espliciti)

Ecco la mia situazione:

Ho un RDD Spark come questo:

val myData: RDD[Array[String]] = ... 

e ho definito un ordinamento per esso:

object MyOrdering extends Ordering[Array[String]] = ... 

Voglio filtrare questo RDD e prendere le prime n voci nel RDD in base al mio ordine. Una scintilla RDD ha un metodo per prendere le voci n top con questa firma:

def top(num: Int)(implicit ord: Ordering[T]): Array[T] 

Inizialmente ho provato questo codice

myData filter { D => 
    D(9) == "yes" 
} top(50)(MyOrdering) 

che non riesce con questo errore:

error: Int(50) does not take parameters 
    } top(50)(MyOrdering) 

Tuttavia, questo codice funziona:

myData.filter(D => D(9) == "yes").top(50)(MyOrdering) 

Per il mio occhio da principiante, l'esempio di codice in errore e l'esempio di codice funzionante sembrano specificare la logica equivalente. Ho sbagliato qui? Sto effettivamente facendo qualcosa di diverso nei due esempi di codice? O si tratta di un problema con il modo in cui il compilatore Scala analizza il codice?

+1

L'errore indica che il primo viene analizzato in modo analogo a '(filtro myData {D => D (9) ==" yes "} top) (50 (MyOrdering))', dove '(50)' non viene preso come parametro del metodo stesso. L'errore riportato può essere minimamente riprodotto con '50 (" Hello! ")', Per esempio. Cioè, anche senza l'implicito (elenco di parametri aggiuntivi), come si analizza? O è solo questa aggiunta che cambia il comportamento della sintassi? – user2864740

+0

Senza l'elenco di parametri impliciti funziona bene, ad esempio questo funziona: 'implicito val myOrd: Ordinamento [Array [String]] = MyOrdering' ' myData filter {D => D (9) == "sì" } top (50) ' –

+0

Un esempio più semplice senza scintilla sarebbe' List (1, 2, 3, 4) filtro (_> 2) sortBy (_ * -1) (scala.math.Ordering.Int) ' –

risposta

1

È possibile sostituire solo il punto . con uno spazio per il richiamo del metodo quando il metodo è arity-1 (1 elenco di parametri) o arity-0 (nessun elenco di parametri). Ad esempio, questo non riesce a compilare:

class Foo { 
    def baz(x: Int)(y: Int) = this 
    def qux(x: Int) = this 
} 

(new Foo) baz(1)(1) //Does not compile 
(new Foo).baz(1)(1) //Allowed 
(new Foo) qux(1) //Allowed, since qux is arity-1 
(new Foo).qux(1) //Also allowed, of course 

Quando l'elenco l'ultimo parametro è implicit il compilatore può trattare un metodo con n liste di parametri come se si ha arity n-1 se il metodo viene richiamato con un argomento implicit:

class Foo { 
    def baz(x: Int)(implicit y: Int) = this 
} 

implicit val y: Int = 1 
(new Foo) baz(1) //Allowed 
(new Foo).baz(1) //Also fine 
(new Foo) baz(1)(2) //Still not allowed 
(new Foo).baz(1)(2) //Still allowed 

Ulteriori informazioni sulle regole per il richiamo del metodo in the style guide.

Problemi correlati