2010-04-22 7 views
2

ZeroC Ice pour Java translates chaque interface de tranche Simple en (entre autres choses) une interface proxy SimplePrx et un proxy SimplePrxHelper. Si j'ai un ObjectPrx (l'interface de base pour toutes les procurations), je peux vérifier si elle possède une interface Simple fait en utilisant une méthode statique sur SimplePrxHelper:ZeroC Ice "jetés jette" dans Scala

val obj : Ice.ObjectPrx = ...;  // Get a proxy from somewhere... 

val simple : SimplePrx = SimplePrxHelper.checkedCast(obj); 
if (simple != null) 
    // Object supports the Simple interface... 
else 
    // Object is not of type Simple... 

Je voulais écrire une méthode castTo pour que je puisse remplacer la deuxième ligne avec

val simple = castTo[SimplePrx](obj) 

ou

val simple = castTo[SimplePrxHelper](obj) 

pour autant que je peux voir, le système de type Scala est n ot assez expressif pour me permettre de définir castTo. Est-ce correct?

+1

Pourquoi ne pas simplement 'simple, val = SimplePrxHelper.checkedCast (obj)'? C'est presque aussi court que ce que tu veux. Sinon, je ne comprends pas comment le système _type_ est censé savoir que cette bibliothèque a défini une relation entre les choses appelées 'FooPrx' et' FooPrxHelper', étant donné que la bibliothèque est organisée de cette façon et non comme 'Helper ' CA devrait etre. –

+0

Parce que je suis moins inquiet d'être court que d'être générique. Je ne peux pas, par exemple, utiliser un tel cast à l'intérieur d'une méthode 'foo [AProxyInterface](): AProxyInterface'. –

Répondre

4

devrait être en mesure de faire quelque chose avec implicits, le long de ces lignes:

object Casting { 
    trait Caster[A] { 
    def checkedCast(obj: ObjectPrx): Option[A] 
    } 

    def castTo[A](obj: ObjectPrx)(implicit caster: Caster[A]) = 
    caster.checkedCast(obj) 

    implicit object SimplePrxCaster extends Caster[SimplePrx] { 
    def checkedCast(obj: ObjectPrx) = Option(SimplePrxHelper.checkedCast(obj)) 
    } 
} 

Alors vous apporter juste des choses dans le périmètre où vous voulez les utiliser:

package my.package 

import Casting._ 

... 
    def whatever(prx: ObjectPrx) { 
    castTo[SimplePrx](prx) foreach (_.somethingSimple()) 
    } 
... 
+0

D'ailleurs, si vous n'aimez pas tous les "objets implicites", vous pouvez le faire de la façon suivante: def castTo [A] (obj: ObjectPrx) (implicite mfst: ClassManifest [A]) = { val helperClass = Class.forName (mfst.erasure.getName + "Aide"); val méthode = helperClass.getMethod ("checkedCast", classOf [ObjectPrx]); Option (method.invoke (null, obj)). AsInstanceOf [Option [A]]} ..plus de gestion d'exception bien sûr. Pas comme type sûr grâce à la fonte effacée, et plutôt plus lent, mais seulement une chose nommée. Modifier: eek, le formatage échoue! –

1

Vous pouvez obtenir quelque chose comme ce que vous voulez avec les types de structure:

def castTo[A](helper: { def checkedCast(o: Object): A })(o: Object) = { 
    helper.checkedCast(o) 
} 
class FooPrx { } 
object FooPrxHelper { 
    def checkedCast(o: Object): FooPrx = o match { 
    case fp : FooPrx => fp 
    case _ => null 
    } 
} 

scala> val o: Object = new FooPrx 
o: java.lang.Object = [email protected] 

scala> val fp = castTo(FooPrxHelper)(o) 
fp: FooPrx = [email protected] 
+0

J'ai pensé à cela, mais malheureusement 'FooPrxHelper' est défini comme une classe (en Java). J'ai "FooPrxHelper n'est pas une valeur". –

+0

@Alexey Vous pouvez envelopper tout à la main (ou pas vraiment à la main - écrire quelque chose qui fera la génération automatique de code pour vous). –

Questions connexes