加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么我不能在没有丑陋的匿名类的情况下在Scala中实现这个Java

发布时间:2020-12-16 10:00:35 所属栏目:安全 来源:网络整理
导读:我在 Java中有以下界面 public interface IPropertyT extends ComparableT { String getName(); CollectionT getAllowedValues(); ClassT getValueClass(); String getName(T value);} 并试图在scala中实现它,但无法让它工作 第一次尝试: class Enumeration
我在 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
    }
  }
}

问题:

>这样做的正确方法是什么?
>为什么enum.Value在我的第一次尝试中不起作用,但在匿名类中使用时是否有效?
>为什么enum.Value和T#Value不一样?
>为什么编译器会抱怨T#Value与Comparable [T]不匹配,因为Value扩展了Ordered [Value],它扩展了Comparable [Value]?

解决方法

啊,使用路径依赖类型的乐趣……

枚举#Value是路径依赖类型.
这是Value的实际类型取决于Enumeration实现的当前实例.

因此,如果你有两个枚举

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用#;)完成

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读