Domanda

In modo semplice, quali sono contestuali e visualizzare i limiti e qual è la differenza tra loro?

Alcuni esempi facili da seguire sarebbe troppo grande!

È stato utile?

Soluzione

Ho pensato che questo è stato chiesto già, ma, in tal caso, la questione non è evidente nella "correlate" bar. Così, qui è:

Che cosa è una vista Bound?

vista vincolati è un meccanismo introdotto in Scala per consentire l'uso di un certo tipo A come fosse qualche tipo B. La sintassi tipica è questa:

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

In altre parole, A dovrebbe avere una conversione implicita a B disponibili, in modo che si può chiamare metodi B su un oggetto di tipo A. Il più uso di vista comuni limiti nella libreria standard (prima di Scala 2.8.0, comunque), è con Ordered, in questo modo:

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

Poiché si può convertire in un A Ordered[A], e poiché Ordered[A] definisce il metodo <(other: A): Boolean, posso utilizzare il a < b espressione.

Si prega di essere consapevole del fatto che vista limiti sono deprecati , si dovrebbe evitare.

Che cosa è un contesto Bound?

limiti di contesto sono stati introdotti in Scala 2.8.0, e sono tipicamente utilizzati con il cosiddetto modello tipo di classe , un modello di codice che emula le funzionalità fornite da classi di tipo Haskell, anche se in un più prolisso modo.

Mentre una vista vincolato può essere utilizzato con tipi semplici (per esempio, A <% String), un contesto vincolato richiede un tipo parametrico , come Ordered[A] sopra, ma String differenza.

Un contesto vincolato descrive un implicito valore , invece di vista della tenuta implicita conversione . E 'usato per dichiarare che per un certo tipo A, v'è un valore implicito di tipo B[A] disponibili. La sintassi è questa:

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

Questo è più confuso di vista legato perché non è immediatamente chiaro come usarlo. L'esempio comune di utilizzo in Scala è questo:

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

Un inizializzazione Array su un tipo parametrico richiede un ClassManifest per essere disponibile, per motivi arcani legati alla cancellazione di tipo e la natura non cancellazione degli array.

Un altro esempio molto comune nella libreria è un po 'più complessa:

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

Qui, implicitly viene utilizzato per retrive il valore implicito che vogliamo, uno di tipo Ordering[A], quale classe definisce il metodo compare(a: A, b: A): Int.

vedremo un altro modo di fare questo qui sotto.

Come sono vista Bounds e contesto Bounds implementate?

Non dovrebbe sorprendere che sia limiti vista e limiti di contesto sono implementati con i parametri impliciti, data la loro definizione. In realtà, la sintassi ho mostrato sono gli zuccheri sintattici per ciò che realmente accade. Vedere di seguito come si de-zuccheri:

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)

Così, naturalmente, si può scriverle in tutta la loro sintassi, che è particolarmente utile per il contesto limiti:

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

Cosa Vedere Bounds utilizzato per?

Visualizza i limiti sono usati per lo più per sfruttare il Pimp My biblioteca modello, attraverso il quale si "aggiunge" i metodi di una classe esistente, in situazioni in cui si desidera restituire il tipo di originale in qualche modo. Se non avete bisogno di tornare quel tipo in qualsiasi modo, quindi non è necessario una vista rilegato.

L'esempio classico di vista utilizzo legato sta gestendo Ordered. Si noti che non è Int Ordered, per esempio, se non v'è una conversione implicita. Nell'esempio precedentemente dato esigenze vista vincolato perché restituisce il tipo non convertito:

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

In questo esempio non funzionerà senza vista limiti. Tuttavia, se dovessi tornare un altro tipo, quindi non ho bisogno di una visione legata più:

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

La conversione here (se necessario) avviene prima di passare il parametro f, so f non ha bisogno di sapere su di esso.

Oltre Ordered, l'uso più comune dalla biblioteca sta gestendo String e Array, che sono classi Java, come se fossero raccolte Scala. Ad esempio:

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

Se uno ha cercato di fare questo senza vista limiti, il tipo di ritorno di un String sarebbe un WrappedString (Scala 2.8), e analogamente per Array.

La stessa cosa accade anche se il tipo viene utilizzato solo come un parametro di tipo di tipo di ritorno:

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

Quali sono Bounds contesto utilizzati per?

limiti di contesto sono utilizzati principalmente in quello che è noto come typeclass modello , come riferimento alle classi di tipo Haskell. Fondamentalmente, questo modello implementa alternativa all'ereditarietà rendendo funzionalità disponibili tramite una sorta di reticolo adattatore implicito.

L'esempio classico è Scala 2.8 di Ordering, che ha sostituito Ordered tutta la biblioteca di Scala. L'utilizzo è:

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

Anche se è solitamente vede che scritto così:

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

che sfruttano alcune conversioni implicite all'interno Ordering che consentono lo stile operatore tradizionale. Un altro esempio in Scala 2.8 è il Numeric:

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

Un esempio più complesso è la nuova collezione di utilizzo CanBuildFrom, ma c'è già una lunga risposta a tale proposito, quindi mi evito qui. E, come accennato prima, c'è l'utilizzo ClassManifest, che è richiesto per inizializzare nuovi array senza tipi concreti.

Il contesto legato con il modello typeclass è molto più probabile per essere utilizzato dalle vostre classi, in quanto consentono la separazione degli interessi, mentre vista limiti possono essere evitati nel proprio codice per il buon design (è usato per lo più per andare in giro qualcun altro disegno).

Anche se è stato possibile per un lungo periodo di tempo, l'uso di contesto limiti è veramente decollato nel 2010, ed è ora trovato in una certa misura nella maggior parte della maggior parte delle librerie e framework importanti della Scala. L'esempio più estremo del suo utilizzo, però, è la biblioteca Scalaz, che porta un sacco di potenza di Haskell alla Scala. Mi raccomando di leggere su modelli typeclass per ottenere più conoscenza che tutti i modi in cui può essere utilizzato.

Modifica

Domande correlate di interesse:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top