Notazione infissa alla Scala


12

È possibile chiamare un metodo usando la notazione infix?

Ad esempio, in Haskell, potrei scrivere la seguente funzione:

x `isAFactorOf` y = x % y == 0

e poi usalo come:

if 2 `isAFactorOf` 10 ...

Che in alcuni casi consente un codice molto leggibile. C'è qualcosa di simile a questo possibile in Scala? Ho cercato "notazione infissa alla Scala", ma quel termine sembra significare qualcosa di diverso in Scala.

Risposte:


15

A partire dalla versione 2.10, Scala ha introdotto le classi implicite per gestire esattamente questo problema.

Ciò eseguirà una conversione implicita su un determinato tipo in una classe spostata, che può contenere i tuoi metodi e valori.

Nel tuo caso specifico, useresti qualcosa del genere:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

Nota che una volta compilato, questo finirà per inscatolare il nostro valore grezzo in a RichInt(2). Puoi aggirare questo dichiarando il tuo RichInt come sottoclasse di AnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

Ciò non causerà il pugilato, ma è più restrittivo di una tipica classe implicita. Può contenere solo metodi, non valori o stato.


2
Dovresti probabilmente menzionare che le classi implicite non possono essere di livello superiore, quindi la classe implicita dovrà essere definita localmente.
Carcigenicato,

3

In sostanza, in Scala non è possibile chiamare una funzione in modo infisso, ma è possibile definire un metodo su un tipo, in cui l'argomento sinistro può essere convertito in modo implicito. Quindi, per il tuo esempio, puoi definire una classe che ha un metodo isAFactorOf (prendendo un Int) e indicare che un Int può essere implicitamente convertito in un'istanza di questa classe.

Se guardi questa risposta /programming//a/3119671 a un'altra domanda, vedrai la sintassi in Scala che funziona in modo equivalente.


Vale la pena di sottolineare che le nuove versioni di Scala hanno un costrutto esplicito per questo, che la risposta legata no indirizzo: implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.