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

Scala Enumerations中的错误(?)类型匹配

发布时间:2020-12-16 09:05:31 所属栏目:安全 来源:网络整理
导读:我有一个枚举类来表示值的类型.该类的代码非常简单: object Type extends Enumeration { type Type = Value val tInt,tBoolean,tString,tColor,tFont,tHAlign,tVAlign,tTextStyle,tUnknown = Value; def fromValue (value:Any) : Type.Type = { value match
我有一个枚举类来表示值的类型.该类的代码非常简单:

object Type extends Enumeration {
  type Type = Value
  val tInt,tBoolean,tString,tColor,tFont,tHAlign,tVAlign,tTextStyle,tUnknown = Value;

  def fromValue (value:Any) : Type.Type = {
    value match {
      case a:Int                 => tInt
      case a:Boolean             => tBoolean
      case a:Color               => tColor
      case a:Font                => tFont
      case a:HAlign.HAlign       => tHAlign
      case a:VAlign.VAlign       => tVAlign
      case a:TextStyle.TextStyle => tTextStyle
      case _                     => tUnknown
    }
  }
}

我在哪里列举了一些东西:

object VAlign extends Enumeration {
  type VAlign = Value
  val top,middle,bottom = Value
}

object HAlign extends Enumeration {
  type HAlign = Value
  val left,center,right = Value
}

object TextStyle extends Enumeration {
  type TextStyle = Value
  val bold,italic,regular = Value
}

那么,为什么会出现以下奇怪之处?:

scala> Type fromValue VAlign.bottom
res3: Type.Type = tHAlign

另外,我怎样才能避免这种怪异?如何从值中进行类型匹配以区分不同的枚举?

解决方法

我相信你正面临一个擦除路径依赖类型的问题(另见下面的编辑2).

让我们先简化一下这个例子:

object Enum1 extends Enumeration {
  val A,B = Value
}
object Enum2 extends Enumeration {
  val C,D = Value
}

def t(x : Any) {
  println(x match {
    case ab : Enum1.Value => "from first enum"
    case cd : Enum2.Value => "from second enum"
    case _ => "other"
  })
}

现在,与您观察到的类似,t(Enum1.A)和t(Enum2.C)都打印“来自第一个枚举”.

什么 – 我最初想到的(参见下面的编辑) – 这里发生的是,在模式中使用:得到的instanceOf测试没有区别于Value的两个路径依赖实例,所以第一个案例总是匹配.

解决此问题的一种方法是匹配枚举的值而不是这些值的类型:

def t2(x : Any) {
  println(x match {
    case Enum1.A | Enum1.B => "from first enum"
    case Enum2.C | Enum2.D => "from second enum"
    case _ => "other"
  })
}

编辑1实际上我的假设与spec所说的不符.根据语言规范(§8.2类型模式):

Type patterns consist of types,type variables,and wildcards. A type
pattern T is of one of the following forms:

  • A reference to a class C,p.C,or T #C. This type pattern matches any non-null instance of the given class. Note that the pre?x
    of the class,if it is given,is relevant for determining class
    instances. For instance,the pattern p.C matches only instances of
    classes C which were created with the path p as pre?x. The bottom
    types scala.Nothing and scala.Null cannot be used as type patterns,
    because they would match nothing in any case.
  • […]

如果我理解正确,instanceOf或等效应该区分这两种情况.

编辑2似乎是this issue的结果.

(编辑:李大同)

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

    推荐文章
      热点阅读