sam*_*mba 4 java collections scala pattern-matching
我编写了一个解析Metrics数据的方法,并且首先遇到了transactionMap类型的问题java.util.Map
.我用JavaConverters解决了它.
def parseMetrics(metric: Metric) = {
import scala.collection.JavaConverters._
metric.transactionMap.asScala.values.map {
case false => "N"
case true => "Y"
}.toList
Run Code Online (Sandbox Code Playgroud)
但之后我在模式匹配true和false值时出错: pattern type is incompatible with expected type, found: Boolean, required: java.lang.Boolean
据我所知,Scala没有链接两个隐式转换.有没有办法使用JavaConverters修复它?
另一个答案提供了解决此问题的合理方法,但没有说明您遇到它的原因或它提出的方法是如何工作的.
斯卡拉标准库不提供从隐式转换java.lang.Boolean
到scala.Boolean
,您可以通过使用动作看reify
在REPL到desugar使用在上下文Java boolean值,其中Scala的布尔预计一些代码:
scala> val x: java.lang.Boolean = true
x: Boolean = true
scala> import scala.reflect.runtime.universe.reify
import scala.reflect.runtime.universe.reify
scala> reify(if (x) 1 else 0)
res0: reflect.runtime.universe.Expr[Int] =
Expr[Int](if (Predef.Boolean2boolean($read.x))
1
else
0)
Run Code Online (Sandbox Code Playgroud)
问题是只是尝试匹配一个java.lang.Boolean
值true
或false
不足以触发转换.您可以通过定义自己的类型来检查这一点,您可以确定您确切知道正在进行的转换:
scala> case class Foo(i: Int); case class Bar(i: Int)
defined class Foo
defined class Bar
scala> implicit def foo2bar(foo: Foo): Bar = Bar(foo.i)
foo2bar: (foo: Foo)Bar
scala> Foo(100) match { case Bar(x) => x }
<console>:17: error: constructor cannot be instantiated to expected type;
found : Bar
required: Foo
Foo(100) match { case Bar(x) => x }
^
Run Code Online (Sandbox Code Playgroud)
这是语言设计决策.可能有可能在这些场景中应用隐式转换,但也可能有一个很好的理由,它们不是(我不熟悉任何相关的讨论或问题,但这不是'意思是他们不存在).
Andy的解决方案工作的原因是,java.lang.Boolean
它处于编译器期望scala.Boolean
(一个条件)并愿意应用Predef.Boolean2boolean
转换的位置.如果您真的想要,您可以手动执行此操作:
def parseMetrics(metric: Metric) = {
import scala.collection.JavaConverters._
metric.transactionMap.asScala.values.map(Predef.Boolean2boolean).map {
case false => "N"
case true => "Y"
}.toList
}
Run Code Online (Sandbox Code Playgroud)
......但至少在我看来,模式匹配Boolean
比使用条件更有点笨拙.
使用if / else而不是match语句进行布尔检查:
def parseMetrics(metric: Metric) = {
import scala.collection.JavaConverters._
metric.transactionMap.asScala.values.map {
x => if (x) "Y" else "N"
}.toList
Run Code Online (Sandbox Code Playgroud)
我的怀疑是,在if语句中,java.lang.Boolean
(我想x
是在这里)可以Boolean
通过import scala.collection.JavaConverters._
... 强制执行,但是match语句没有执行相同的强制操作,而必须显式地进行(或在java.lang.Boolean
值上进行匹配) 。
归档时间: |
|
查看次数: |
291 次 |
最近记录: |