为什么我不能在没有丑陋的匿名类的情况下在Scala中实现这个Java
我在
Java中有以下界面
public interface IProperty<T extends Comparable<T>> { String getName(); Collection<T> getAllowedValues(); Class<T> getValueClass(); String getName(T value); } 并试图在scala中实现它,但无法让它工作 第一次尝试: class EnumerationProperty1[T <: Enumeration](val enum: T,val name: String) extends IProperty[enum.Value] { override def getName = name override def getValueClass = classOf[enum.Value] override def getName(value: enum.Value): String = value.toString override def getAllowedValues: java.util.Collection[enum.Value] = enum.values.toList } 不编译时出错:找不到:值枚举 第二次尝试: class EnumerationProperty2[T <: Enumeration](val enum: T,val name: String) extends IProperty[T#Value] { override def getName = name override def getValueClass = classOf[T#Value] override def getName(value: T#Value): String = value.toString override def getAllowedValues: java.util.Collection[T#Value] = enum.values.toList } 不使用Error编译:类型参数[T#Value]不符合特征IProperty的类型参数bounds [T<:Comparable [T]] 最后我找到了一种方法,但它对我来说看起来很难看: object EnumerationPropertyAnonymous { def create[T <: Enumeration](enum: T,name: String) = { new IProperty[enum.Value] { override def getName = name override def getValueClass = classOf[enum.Value] override def getName(value: enum.Value): String = value.toString override def getAllowedValues: java.util.Collection[enum.Value] = enum.values.toList } } } 问题: >这样做的正确方法是什么? 解决方法
啊,使用路径依赖类型的乐趣……
枚举#Value是路径依赖类型. 因此,如果你有两个枚举 object A extends Enumeration { val first = Value(0,"first") } object B extends Enumeration { val first = Value(0,"first") } 以下条件返回false. A.first == B.first A.first.isInstanceOf[B.first.type] 但这是事实 A.first.isInstanceOf[Enumeration#Value] 有关路径相关类型的更多信息,请参阅此article 对于问题: @ 1)这取决于你想要完成的事情.一个快速的方法是与工厂.有点类似于你的“匿名”示例,但有点像scala-ish: // it is recommended to use converters instead of conversions. import scala.collection.JavaConverters._ case class EnumPropertyFactory[T <: Enumeration](val enum: T) { def apply(name: String) = new EnumerationProperty(name) class EnumerationProperty(val name: String) extends IProperty[enum.Value] { override def getName = name override def getValueClass = classOf[enum.Value] override def getName(value: enum.Value): String = value.toString override def getAllowedValues: java.util.Collection[enum.Value] = enum.values.toList.asJavaCollection } } // can be used with something like val enum1PropertyFactory = EnumPropertyFactory(EnumOne) val foo = enum1PropertyFactory("foo") val bar = enum1PropertyFactory("bar") @ 2)因为在第一个例子中,enum是一个构造函数参数,在第二个例子中它是一个本地val.记住java中类定义的样子: class EnumerationProperty1<T extends Enumeration> extends IProperty<enum.Value> { public EnumerationProperty1(T enum,String name) { ... } } 这里很清楚,为什么在调用构造函数之前无法知道枚举. @ 3)见上文:路径依赖类型 @ 4)我害怕,这有点高于我.但我敢打赌,它与Enumeration#Value有关,因为路径依赖,而voodoo用#;)完成 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |