2016-11-20 4 views
2

Ich weiß value class in Scala Inline die Operation zum Zeitpunkt des Compilers.Scala Wert Klasse, Anwendungsfälle

vielleicht wie dies

case class A(i: Int) extends AnyVal { 
    def +(that: A) = A(this.i + that.i) 
} 
A(1) + A(2) // After compile it equals to 1 + 2 

aber es scheint keine große Sache für mich.

Es könnte die Leistung verbessern, aber

this.i + that.i Aufruf scheint nicht so viel langsamer als i + i

Warum brauchen wir value class in scala und alle Anwendungsfälle ???

+0

* Aufruf this.i + Das scheint mir nicht viel langsamer als ich. * Wie haben Sie das festgestellt? Haben Sie diesen Code mikrobenchmarkiert? –

+0

Abgesehen von der Tatsache, dass der Aufruf schneller ist (was höchstwahrscheinlich immer vom JIT-Compiler inline ausgeführt wird), vermeiden Wertklassen die Objektinstanziierung, wodurch die Garbage Collection-Last reduziert wird. – Suma

Antwort

5

Warum würden Sie einen einzelnen Wert in eine zusätzliche Klasse einfügen?

Ein großer Anwendungsfall ist die Typensicherheit. Angenommen, Sie Funktion haben, das Geld vermehren kann, etwa so:

def multiply(factor: Int, amount: Int): Int = ??? 

Das Problem dabei ist, dass es sehr einfach sein würde, die zwei Argumente zu verwirren und damit die Funktion falsch nennen. Mit Werten Klassen, könnten Sie eine Money Art erstellen und neu schreiben, die Funktion wie folgt:

case class Money(amount: Int) extends AnyVal 
def multiply(factor: Int, amount: Money): Money = ??? 

Jetzt mit Ihrem speziellen Money Typ, wird der Compiler Ihnen sagen, wenn Sie versuchen, Argumente in der falschen Reihenfolge zu übergeben.

Wenn es sich nicht um eine Wertklasse handelt, kann man sagen, dass die hinzugefügte Sicherheit in manchen Fällen die Leistung nicht wert ist. Bei Wertklassen haben Sie jedoch keinen Laufzeitaufwand (Einschränkungen gibt es jedoch: http://docs.scala-lang.org/overviews/core/value-classes.html).

Eine Alternative das gleiche Ziel sind unboxed (keine Laufzeit-Overhead) markierte Typen in scalaz zu erreichen: http://eed3si9n.com/learning-scalaz/Tagged+type.html

Beachten Sie, dass zum Beispiel Haskell verwendet newtype für die gleiche Idee: https://wiki.haskell.org/Newtype

+0

Danke für Ihre Hilfe. –

1

Wertklassen sind ein Mechanismus in Scala, um die Zuweisung von Laufzeitobjekten zu vermeiden. Dies wird durch die Definition neuer AnyVal-Unterklassen erreicht.

Mehr über Wertklassen ist hier Value Classes

6

Blick Lassen Sie uns an, wie Scala arbeitet mit Wertklassen (-print Option).

case class A(i: Int) extends AnyVal { 
    def +(that: A) = A(this.i + that.i) 
} 
A(1) + A(2) 

wird übersetzt:

final def +$extension($this: Int, that: Int): Int = $this.+(that) 
... 
A.+$extension(1, 2) 

Wie Sie A Scala vermeidet das Arbeiten mit Klasse sehen und fügt einfach Int-IntInt zurück. Zur gleichen Zeit:

case class A(i: Int) { 
    def +(that: A) = A(this.i + that.i) 
} 
A(1) + A(2) 

wird übersetzt:

def +(that: A): A = new A(this.i().+(that.i())) 
... 
new A(1).+(new A(2)) 

So 1 + 2 Sie Klasse A dreimal müssen berechnen instanziiert.

+0

was für eine großartige Erklärung! danke für dein detail. Leistung Kosten von nicht mit Wertklasse scheint offensichtlich –