Scala 零碳冰“;“检查铸件”;在斯卡拉

Scala 零碳冰“;“检查铸件”;在斯卡拉,scala,types,ice,Scala,Types,Ice,ZeroC Ice for Java将每个片接口Simple转换为代理接口SimplePX和代理SimplePXHelper。如果我有一个ObjectPrx(所有代理的基本接口),我可以使用SimpleXHelper上的静态方法检查它是否确实有接口Simple: val obj : Ice.ObjectPrx = ...; // Get a proxy from somewhere... val simple : SimplePrx = SimplePrxHelper.check

ZeroC Ice for Java将每个片接口
Simple
转换为代理接口
SimplePX
和代理
SimplePXHelper
。如果我有一个
ObjectPrx
(所有代理的基本接口),我可以使用
SimpleXHelper
上的静态方法检查它是否确实有接口
Simple

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...
我想写一个方法
castTo
,这样我就可以用

val simple = castTo[SimplePrx](obj)


就我所见,Scala的类型系统没有足够的表达能力来定义
castTo
。这是否正确?

您可以通过结构类型获得所需的内容:

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 = FooPrx@da8742

scala> val fp = castTo(FooPrxHelper)(o)
fp: FooPrx = FooPrx@da8742

应该能够用隐式语言做一些事情,大致如下:

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))
  }
}
然后,您只需在您希望使用它们的范围内使用它们:

package my.package

import Casting._

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

为什么不干脆
val simple=simplerpxhelper.checkedCast(obj)
?它几乎和你想要的一样短。否则,我不清楚类型系统应该如何知道这个特定的库定义了名为
FooPrx
FooPrxHelper
的事物之间的关系,因为库是这样组织的,而不是像它“应该”那样的
Helper
是的。因为我不太担心自己个子矮,而更担心自己是个普通人。例如,我不能在方法
foo[AProxyInterface]():AProxyInterface
中使用这样的强制转换。我确实想到了这一点,但不幸的是
FooPrxHelper
被定义为类(在Java中)。我得到了“FooPrxHelper不是一个值”。@Alexey你可以手工包装所有东西(或者不是真的手工包装——写一些可以为你自动生成代码的东西)。因此,如果你不喜欢所有的“隐式对象”,你可以这样做:def castTo[a](obj:ObjectPrx)(隐式mfst:ClassManifest[a])={val helperClass=Class.forName(mfst.erasure.getName+“Helper”);val method=helperClass.getMethod(“checkedCast”,classOf[ObjectPrx]);Option(method.invoke(null,obj)).asInstanceOf[Option[A]}..当然还有异常处理。由于删除的强制转换,它的类型不安全,而且速度较慢,但只有一个命名的东西。编辑:eek,格式化失败!
package my.package

import Casting._

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