下面的代码检查基本身份验证.这resp是401未经授权的回复.我检查是否存在Authorization标题,如果存在,我验证其值,否则我调用resp:
def validate(authHeader: String): Boolean = {
//........
}
val authHeader = Option(request.getHeader("Authorization"))
authHeader match {
case Some(header) if header.startsWith("Basic ") => validate(header) match { case false => resp }
case _ => resp
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,它给行match { case false => resp }说错误found: scala.Boolean(false) required: java.lang.Boolean.我很困惑为什么它处理scala布尔不同于java布尔值.
我注意到import java.lang._文件开头有一行(我不知道为什么).我评论了它,代码发出警告而不是错误:
warning: match may not be exhaustive.
It would fail on the following input: true
Run Code Online (Sandbox Code Playgroud)
我想这是因为我没有写过case true.但究竟是什么导致了原始错误发生,为什么它只会发生import java.lang._?
编辑:
以下是该问题的最小示例:
val f: java.lang.Boolean = false
val f2: scala.Boolean = false
/* The following line produces this error:
error: type mismatch;
found : scala.Boolean(false)
required: java.lang.Boolean
*/
f match { case false => 5 }
/* The following line produces this warning:
warning: match may not be exhaustive.
It would fail on the following input: true
*/
f2 match { case false => 5 }
Run Code Online (Sandbox Code Playgroud)
看来隐式转换在模式匹配的情况下不起作用。
考虑:
scala> case class Foo(x: Int)
defined class Foo
scala> case class Bar(x: Int)
defined class Bar
scala> implicit def foo2bar(x: Foo) = Bar(x.x)
foo2bar: (x: Foo)Bar
scala> Foo(3) match { case Foo(3) => 3; case _ => 4 }
res19: Int = 3
scala> Foo(3) match { case Bar(3) => 3; case _ => 4 }
<console>:14: error: constructor cannot be instantiated to expected type;
found : Bar
required: Foo
Foo(3) match { case Bar(3) => 3; case _ => 4 }
^
Run Code Online (Sandbox Code Playgroud)
与之比较:
scala> val f: java.lang.Boolean = false
f: Boolean = false
scala> f.<TAB>
asInstanceOf booleanValue compareTo isInstanceOf toString
scala> f || true
res21: Boolean = true
Run Code Online (Sandbox Code Playgroud)
隐式转换在这里起作用,但在这里不起作用:
scala> f match { case false => 3; case true => 4 }
<console>:15: error: type mismatch;
found : scala.Boolean(false)
required: java.lang.Boolean
f match { case false => 3; case true => 4 }
^
<console>:15: error: type mismatch;
found : scala.Boolean(true)
required: java.lang.Boolean
f match { case false => 3; case true => 4 }
^
Run Code Online (Sandbox Code Playgroud)
我同意这是相当违反直觉的,但我怀疑它是否可以在不向语言引入特殊大小写的情况下修复,或者以scalac某种方式识别所有模式都属于单一类型的模式匹配,并尝试找到到该类型的隐式转换。解决方法是进行显式强制asInstanceOf[Boolean]转换。尽管奇怪的是以下工作正常:
scala> "foobar".startsWith("foo") match { case true => 3 ; case false => 4 }
res26: Int = 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1770 次 |
| 最近记录: |