2015-03-30 16 views
5

Dopo aver esaminato alcuni esempi, devo dire, non riesco a capire cosa porti il ​​polimorfico F-Bounded.spiegazione dei tipi scala f

Per utilizzare l'esempio dalla scuola scala (https://twitter.github.io/scala_school/advanced-types.html#fbounded)

Spiegano che hanno bisogno di un certo tipo F-Delimitata in modo che la sottoclasse può restituire il sottotipo. in modo da fare qualcosa di simile:

trait Container[A <: Container[A]] extends Ordered[A] 
class MyContainer extends Container[MyContainer] { 
    def compare(that: MyContainer) = 0 
} 

Ma non vedo qual è il guadagno di utilizzare questo tipo di tipo quando si potrebbe usare qualcosa di simile:

trait Container[A] extends Ordered[A] 
class MyContainer extends Container[MyContainer] { 
    def compare(other: MyContainer) = 0 
} 

Ogni spiegazione è molto accolto

Grazie

risposta

4

Il vantaggio sarebbe venuto quando sembra qualcosa di simile:

trait Container[A <: Container[A]] extends Ordered[A] { 
    def clone: A 
    def pair: (A, A) = (clone, clone) 
} 

class MyContainer extends Container[MyContainer] { 
    def clone = new MyContainer 
} 

Ora si ottiene pair gratuitamente e si ottiene il tipo di reso corretto. Senza qualcosa del genere, è necessario sovrascrivere manualmente ogni singolo metodo che restituisce lo stesso tipo (un sacco di inutili caratteri), oppure si perde la specificità nei tipi non appena si chiama un metodo non sovrascritto.

+1

Penso di aver ottenuto il punto di Nishan e per me ha senso, ma la parte di cui stai parlando è la parte che mi confonde. Dal tuo esempio, potresti definire A come: tratto Container [A] e ottenere lo stesso risultato. Non dovrai sovrascrivere la funzione di accoppiamento nel subcassa –

+0

Oh, non importa, l'ho appena ricevuto. Se si seleziona Container [A], non è possibile garantire che dalla sottoclasse il tipo A restituito sia di tipo Container. molte grazie –

1

In Scala è possibile rendere i parametri del tipo vincolati da un vincolo di tipo. Qui nel tuo primo metodo stai rendendo il tuo parametro di tipo che fa il limite superiore con la sotto classe di Container.

Utilizzando il 1o metodo non è possibile passare il parametro nella classe Contenitore che non è sotto classe della classe Contenitore.

Nel secondo esempio è possibile passare l'istanza del tipo di parametro di qualsiasi classe. Quindi qui non stai restringendo nulla mentre nel primo esempio stai limitando il tipo di sottotipo di classe Container.