Frage

In einer einfachen Art und Weise, was Kontext und Blick Grenzen und was ist der Unterschied zwischen ihnen?

Einige leicht zu folgen Beispiele wären auch toll sein!

War es hilfreich?

Lösung

Ich dachte, das bereits gefragt wurde, aber wenn ja, die Frage in den „verwandten“ nicht ersichtlich ist bar. Also, hier ist es:

Was ist eine Ansicht Bound?

A Ansicht gebunden war ein Mechanismus in Scala eingeführt, um die Verwendung eines Typ A aktivieren als ob es irgendeine Art B war. Die typische Syntax ist folgende:

def f[A <% B](a: A) = a.bMethod

Mit anderen Worten, A sollte eine implizite Konvertierung zur Verfügung zu B haben, so dass man B Methoden auf ein Objekt vom Typ A aufrufen können. Die häufigste Verwendung Blick Grenzen in der Standardbibliothek (vor Scala 2.8.0 jedenfalls), ist mit Ordered, wie folgt aus:

def f[A <% Ordered[A]](a: A, b: A) = if (a < b) a else b

Weil man A in eine Ordered[A] umwandeln kann, und weil Ordered[A] die Methode <(other: A): Boolean definiert, kann ich den Ausdruck a < b verwenden.

Bitte beachten Sie, dass Ansicht Grenzen veraltet sind, sollten Sie sie vermeiden.

Was ist ein Context gebunden?

Kontext Grenzen wurden in Scala 2.8.0 eingeführt und werden in der Regel mit den sogenannten Typklasse Mustern verwenden , ein Muster von Code, der die Funktionalität von Haskell Typklassen, wenn auch in einem vorgesehenen emuliert ausführliche Art und Weise.

Während eine Ansicht gebunden ist, kann mit einfachen Typen verwendet werden (beispielsweise A <% String), verpflichtet, ein Zusammenhang, einen parametrisierte Typ , wie Ordered[A] oben, aber im Gegensatz zu String.

gebunden Ein Kontext beschreibt eine implizite Wert , statt nach Ansicht der impliziten gebunden Umwandlung . Es wird verwendet für eine Art A zu erklären, dass es einen impliziter Wert vom Typ B[A] zur Verfügung steht. Die Syntax lautet wie folgt:

def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]

Das ist mehr verwirrend als die Ansicht gebunden, weil es nicht sofort klar, wie es zu benutzen. Das gemeinsame Beispiel für die Nutzung in Scala ist dies:

def f[A : ClassManifest](n: Int) = new Array[A](n)

Eine Array Initialisierung auf einem parametrisierte Typ erfordert eine ClassManifest zur Verfügung zu stehen, für arkanen Gründe im Zusammenhang mit Typ Löschung und der Nicht-Lösch Art von Arrays.

Ein weiteres sehr bekanntes Beispiel in der Bibliothek ist ein wenig komplexer:

def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)

Hier implicitly wird verwendet, um den impliziten Wert retrive wir wollen, einen vom Typ Ordering[A], die Klasse der Methode compare(a: A, b: A): Int definiert.

Wir werden sehen, einen anderen Weg, dies zu tun unten.

Wie sind Ansicht Bounds und Context Bounds umgesetzt?

Es sollte nicht überraschen, dass beide Ansicht Grenzen und Kontext Grenzen sind mit impliziten Parametern implementiert, da ihre Definition. Eigentlich ist die Syntax Ich zeigte syntaktischer Zucker für das, was wirklich passiert. Im folgenden sehen Sie, wie sie de-Zucker:

def f[A <% B](a: A) = a.bMethod
def f[A](a: A)(implicit ev: A => B) = a.bMethod

def g[A : B](a: A) = h(a)
def g[A](a: A)(implicit ev: B[A]) = h(a)

Also, natürlich, man kann sich in ihrer vollen Syntax schreiben, die für den Kontext Grenzen besonders nützlich ist:

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)

Was Ansicht Bounds verwendet?

Ansicht Grenzen werden verwendet, meist Vorteil der , um meine Bibliothek pimp Muster, durch die man „ergänzt“ Methoden zu einer bestehenden Klasse, in Situationen, in denen Sie irgendwie den ursprünglichen Typ zurückzukehren. Wenn Sie nicht brauchen diese Art in irgendeiner Weise zurück, dann brauchen Sie nicht eine Ansicht gebunden ist.

Das klassische Beispiel für Ansicht gebundener Nutzung ist der Umgang mit Ordered. Beachten Sie, dass Int nicht ist Ordered, zum Beispiel, wenn es eine implizite Konvertierung ist. Das Beispiel vorher braucht eine Ansicht gegeben gebunden, weil sie den nicht umgesetzten Typ zurückgibt:

def f[A <% Ordered[A]](a: A, b: A): A = if (a < b) a else b

In diesem Beispiel wird ohne Sicht Grenzen nicht. Wenn ich jedoch eine andere Art zurückkehren würde, dann brauche ich keine Aussicht gebunden mehr:

def f[A](a: Ordered[A], b: A): Boolean = a < b

Die Umwandlung hier (bei Bedarf) passiert, bevor ich die Parameter auf f, s übergebeo f braucht nicht darüber zu wissen.

Neben Ordered, die am weitesten verbreitete Anwendung aus der Bibliothek ist der Umgang mit String und Array, die Java-Klassen sind, wie sie Scala Sammlungen waren. Zum Beispiel:

def f[CC <% Traversable[_]](a: CC, b: CC): CC = if (a.size < b.size) a else b

Wenn man versucht, diese Grenzen ohne Sicht zu tun, der Rückgabetyp eines String wäre ein WrappedString (Scala 2.8), und in ähnlicher Weise für Array.

Das gleiche geschieht auch, wenn der Typ nur als Typ-Parameter des Rückgabetypen verwendet wird:

def f[A <% Ordered[A]](xs: A*): Seq[A] = xs.toSeq.sorted

Was Context Bounds verwendet, für den?

Kontext Grenzen werden vor allem in dem, was bekannt geworden ist als typeclass Muster , als Verweis auf Haskells Typklassen. Im Allgemeinen ist dieses Muster implementiert eine Alternative zur Vererbung von Funktionalität zur Verfügung zu durch eine Art impliziter Adapter-Muster.

Das klassische Beispiel ist Scala 2.8 des Ordering, die Ordered ganze Scala Bibliothek ersetzt. Die Nutzung ist:

def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b

Auch wenn Sie in der Regel sehen, dass wie folgt geschrieben:

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = {
    import ord.mkOrderingOps
    if (a < b) a else b
}

Welche Vorteil einiger impliziten Konvertierungen innerhalb Ordering nehmen, dass die traditionellen Betreiber Stil ermöglichen. Ein weiteres Beispiel in Scala 2.8 ist die Numeric:

def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b)

Ein komplexeres Beispiel ist die neue Kollektion Nutzung von CanBuildFrom, aber es ist schon eine sehr lange Antwort darüber, so dass ich es hier vermeiden würde. Und, wie bereits erwähnt, gibt es die ClassManifest Nutzung, die neue Arrays ohne konkrete Typen zu initialisieren erforderlich ist.

Der Zusammenhang mit dem typeclass Muster gebunden ist viel wahrscheinlicher, indem Sie Ihre eigenen Klassen verwendet werden, da sie Trennung von Bedenken ermöglichen, während Ansicht Grenzen können in Ihrem eigenen Code durch gutes Design vermieden werden (es verwendet wird, meist zu umgehen jemand anderes Design).

in den meisten Scala wichtigsten Bibliotheken und Frameworks

Auch wenn es für eine lange Zeit möglich ist, wird die Verwendung von Kontext Grenzen wirklich im Jahr 2010 genommen und ist nun zu einem gewissen Grad gefunden. Das extremste Beispiel für die Verwendung, allerdings ist die Scalaz Bibliothek, die viel von der Kraft des Haskell Scala bringt. Ich empfehle die Lektüre auf typeclass Muster auf mehr kennen lernen es alle Möglichkeiten, in denen sie verwendet werden können.

Bearbeiten

ähnliche Fragen von Interesse:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top