2010-06-21 2 views

Répondre

11

Le problème ici est que les deux déclarations suivantes sont différentes :

def homepageClass[A <: SomeType]: Class[A] // has type parameters 
def homepageClass = classOf[SomeOtherType] // doesn't have type parameters 

pour accomplir ce que vous voulez, vous devez déclarer un type abstrait, comme celui-ci:

trait SomeTrait{ 
    type A <: SomeType 
    def homepageClass: Class[A] 
} 

object SomeObject extends SomeTrait { 
    type A = SomeOtherType 
    def homepageClass: Class[A] = classOf[SomeOtherType] 
} 

Ou

trait SomeTrait[A <: SomeType] { 
    def homepageClass: Class[A] 
} 


object SomeObject extends SomeTrait[SomeOtherType] { 
    def homepageClass: Class[SomeOtherType] = classOf[SomeOtherType] 
} 
2
def homepageClass[A <: SomeType]: Class[A] 

dit « quelle que soit la sous-classe A de SomeType que vous donnez, je peux retourner un Class[A]. En particulier, il peut être appelé comme ceci:

class SomeThirdType extends SomeType 

val x: Class[SomeThirdType] = SomeObject.homepageClass[SomeThirdType] 

Un équivalent plus direct que Daniel donne est un type existentiel:

trait SomeTrait{ 
    def homepageClass: Class[A forSome {type A <: SomeType}] 
} 

ou

trait SomeTrait{ 
    def homepageClass: Class[_ <: SomeType] 
} 

MISE À JOUR: Deux différences entre les solutions Je peux penser à:

  1. Les types existentiels produisent le même bytecode que les jokers Java (et their major intended use is interoperation with wildcards).

  2. Vous pouvez écrire un type de raffinement pour la solution de membre de type abstrait:

    val x: SomeTrait {type A = SomeOtherType} = SomeObject 
    

    Je ne pense pas que vous pouvez pour les types existentiels.

D'autres?

+0

Si vous expliquez maintenant la différence entre ma suggestion et la version existentielle, ce serait génial! :-) –

Questions connexes