Scala-Infix-Notation


12

Ist es möglich, eine Methode mit Infix-Notation aufzurufen?

In Haskell könnte ich beispielsweise die folgende Funktion schreiben:

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

und dann benutze es wie:

if 2 `isAFactorOf` 10 ...

Dies ermöglicht in einigen Fällen einen gut lesbaren Code. Ist in Scala etwas Ähnliches möglich? Ich habe nach "Scala-Infix-Notation" gesucht, aber dieser Begriff scheint in Scala etwas anderes zu bedeuten.

Antworten:


15

Ab Version 2.10 führte Scala implizite Klassen ein, um genau dieses Problem zu lösen.

Dadurch wird eine implizite Konvertierung eines bestimmten Typs in eine umschlossene Klasse durchgeführt, die Ihre eigenen Methoden und Werte enthalten kann.

In Ihrem speziellen Fall würden Sie Folgendes verwenden:

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

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

Beachten Sie, dass beim Kompilieren unser Rohwert in a gepackt wird RichInt(2). Sie können dies umgehen, indem Sie Ihr RichInt als Unterklasse von deklarieren AnyVal:

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

Dies verursacht kein Boxen, ist jedoch restriktiver als eine typische implizite Klasse. Es kann nur Methoden enthalten, keine Werte oder Zustände.


2
Sie sollten wahrscheinlich erwähnen, dass implizite Klassen nicht die oberste Ebene sein können, daher muss die implizite Klasse lokal definiert werden.
Carcigenicate

3

Im Wesentlichen können Sie in Scala eine Funktion nicht auf Infix-Weise aufrufen, sondern Sie können eine Methode für einen Typ definieren, in die das linke Argument implizit konvertiert werden kann. In Ihrem Beispiel können Sie also eine Klasse mit der Methode isAFactorOf (unter Verwendung eines Int) definieren und angeben, dass ein Int implizit in eine Instanz dieser Klasse konvertiert werden kann.

Wenn Sie sich diese Antwort /programming//a/3119671 auf eine andere Frage ansehen , sehen Sie die Syntax in Scala, die gleichwertig funktioniert.


Es sei darauf hingewiesen, dass neue Versionen von Scala explizit ein Konstrukt dafür haben, das in der verknüpften Antwort nicht behandelt wird : implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.