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

Scala中的模式匹配结构类型

发布时间:2020-12-16 09:36:53 所属栏目:安全 来源:网络整理
导读:为什么打印wtf?模式匹配在结构类型上不起作用吗? "hello" match { case s: { def doesNotExist(i: Int,x: List[_]): Double } = println("wtf?") case _ = println("okie dokie") } 解决方法 在Scala解释器中运行此示例,并在(scala -unchecked)上显示未检
为什么打印wtf?模式匹配在结构类型上不起作用吗?

"hello" match {
    case s: { def doesNotExist(i: Int,x: List[_]): Double } => println("wtf?")
    case _ => println("okie dokie")
  }

解决方法

在Scala解释器中运行此示例,并在(scala -unchecked)上显示未检查的警告,将产生以下警告:警告:细化AnyRef {def doesNotExist(Int,List [_]):类型模式中的Double}由于被擦除而消除。不幸的是,像这样的一般类型不能在运行时检查,因为JVM没有经过泛化的泛型。

JVM在此模式中看到的所有匹配项是:

"hello" match {
  case s: Object => ... 
  case annon: Object => ...
}

编辑:为了回应你的意见,我一直在想一个解决方案,但没有时间发布昨天。不幸的是,即使它有效,编译器无法注入适当的清单。

要解决的问题是比较一个对象是否是给定的结构类型。这是我一直在想的一些代码(Scala 2.8-r20019,Scala 2.7.6.final在我玩几次,类似的想法的时候崩溃了)

type Foo = AnyRef { def doesNotExist(i: Int,x: List[_]): Double }

def getManifest[T](implicit m: Manifest[T]) = m

def isFoo[T](x: T)(implicit mt: Manifest[T]) = 
  mt == getManifest[Foo]

方法isFoo基本上比较了Foo类x的清单。在一个理想的世界中,结构类型的清单应该等于包含所需方法的任何类型的清单。至少这是我的思路。不幸的是,当调用getManifest [Foo]时,编译器会注入一个Manifest [AnyRef]而不是一个Manifest [Foo]。有趣的是,如果您不使用结构类型(例如,键入Foo = String),则此代码按预期编译和工作。我会在某个时候发布一个问题,看看为什么这种结构类型失败 – 这是一个设计决策,还是只是一个实验反思API的问题。

否则,您可以随时使用Java反射来查看对象是否包含方法。

def containsMethod(x: AnyRef,name: String,params: java.lang.Class[_]*) = {
  try { 
    x.getClass.getMethod(name,params: _*)
    true
    }
  catch {
    case _ =>  false
  }
}

其工作原理如下:

containsMethod("foo","concat",classOf[String]) // true
containsMethod("foo","bar",classOf[List[Int]]) // false

…但它不是很好

另外请注意,结构类型的结构在运行时不可用。如果你有一个方法def foo(x:{def foo:Int})= x.foo,擦除后你会得到def foo(x:Object)= [一些反映在x上调用foo的方式],类型信息丢失。这就是为什么首先使用反射,因为您必须在对象上调用一个方法,并且JVM不知道Object是否具有该方法。

(编辑:李大同)

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

    推荐文章
      热点阅读