2010-01-20 6 views
4

Dans Scala, comment puis-je ajouter un trait de conteneur (comme Traversable [Contenu]) à un autre qui étend le récipient (et a ainsi limité la visibilité de son contenu?Dépendance en traits héritage

Par exemple, le code ci-dessous tente de définir un WithIter trait pour un conteneur nécessitant Traversable (bien sûr, j'ai en fait d'autres choses dans le conteneur)

import scala.collection._ 

trait Container { 
    type Value 
} 

trait WithIter extends Container with immutable.Traversable[Container#Value] 

class Instance extends WithIter { 
    type Value = Int 
    def foreach[U](f : (Value) => (U)) : Unit = {} 
} 

compilateur (scalac 2.8.0.Beta1-de RC8) trouve une erreur.

error: class Instance needs to be abstract, since method foreach in trait GenericTraversableTemplate of type [U](f: (Container#Value) => U)Unit is not defined

Y a-t-il un moyen simple?

Répondre

4
class Instance extends WithIter { 
    type Value = Int 
    def foreach[U](f : (Container#Value) => (U)) : Unit = {} 
} 

Si vous ne spécifiez pas OuterClass# en parlant d'une classe interne, puis this. (c.-à-spécifique par exemple) seront pris en charge.

+0

Je suis un peu confus par la construction. Vous ne pouvez pas dire: new Instance(). Foreach ((x: Int) => x + 1). Pourquoi le définirais-tu comme ça? –

+0

Cette construction peut être utile lorsque vous voulez quelque chose qui fonctionne comme Int mais qui est incompatible - par exemple, si vous définissez une devise ou des unités de mesure. –

+0

@Thomas: Ce n'est pas _my_ construct. Étant donné la définition de 'WithIter' de la question, c'est la façon correcte de déclarer' Instance'. –

2

Pourquoi utilisez-vous un type abstrait? Les génériques sont simples:

import scala.collection._ 

trait Container[T] {} 

trait WithIter[T] extends Container[T] with immutable.Traversable[T] 

class Instance extends WithIter[Int] { 
    def foreach[U](f : (Int) => (U)) : Unit = {println(f(1))} 
} 


new Instance().foreach((x : Int) => x + 1)