Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:参数化中完全限定类名的模式匹配问题_Scala_Pattern Matching - Fatal编程技术网

Scala:参数化中完全限定类名的模式匹配问题

Scala:参数化中完全限定类名的模式匹配问题,scala,pattern-matching,Scala,Pattern Matching,当使用完全限定的类名对Scala中的对象进行参数化时,我在模式匹配方面遇到了一个小问题。这是基于Scala 2.9.0.1的。有人知道这个代码有什么问题吗 scala> "foo" match { | case y : Seq[Integer] => | case y : Seq[java.lang.Integer] => <console>:3: error: ']' expected but '.' found. case y : Seq[java.l

当使用完全限定的类名对Scala中的对象进行参数化时,我在模式匹配方面遇到了一个小问题。这是基于Scala 2.9.0.1的。有人知道这个代码有什么问题吗

scala> "foo" match {
 | case y : Seq[Integer] =>
 | case y : Seq[java.lang.Integer] =>
<console>:3: error: ']' expected but '.' found.
   case y : Seq[java.lang.Integer] =>
scala>“foo”匹配{
|案例y:序号[整数]=>
|案例y:Seq[java.lang.Integer]=>
:3:错误:']'应为,但找到''。
案例y:Seq[java.lang.Integer]=>

为什么第一个版本可以工作,但后一个版本失败了?问题似乎只有在使用完全限定的类名进行参数化时才会出现。

事实上,您的第一个示例也不起作用。如果运行REPL时未选中-unchecked,您将看到以下错误:

警告:类型模式Seq[Integer]中的非变量类型参数Integer未选中,因为它已通过擦除消除

因此,您实际上无法执行您试图执行的操作—在运行时,List[Integer]和List[AnythingElse]之间没有区别,因此您无法在其上进行模式匹配。您可能可以使用清单执行此操作,请参阅和

第8.1节模式,第8.2节中定义的:后的标识符需要是类型模式:

类型模式由类型、类型变量和通配符组成 模式T为以下形式之一:

一种参数化类型模式T[A(1),…,A(n)],其中A(i)是 键入变量模式或通配符。此类型模式与所有 与类型的某些任意实例化的T匹配的值 变量和通配符。这些类型的边界或别名类型 变量的确定如(§8.3)所述

类型变量模式是以 小写字母。但是,预定义的基元类型别名 单位、布尔值、字节、短字符、字符、整型、长字符、浮点值和双精度值都不是 分类为类型变量模式

因此,在语法上,您不能在此位置使用完全限定类作为类型变量模式。但是,您可以使用类型别名,因此:

type JavaInt = java.lang.Integer
List(new java.lang.Integer(5)) match {
    case y: Seq[JavaInt] => 6
    case _ => 7
}
将按预期返回6。问题是,正如Alan Burlison指出的,以下内容也将返回6:

List("foobar") match {
    case y: Seq[JavaInt] => 6
    case _ => 7
}

因为类型正在被擦除。您可以通过运行REPL或带有-unchecked选项的scalac来看到这一点。

我不认为类型擦除是问题的关键。这样如何:
“foo”。asInstanceOf[Any]match{

case x:Seq[Integer]=>

case y:Seq[java.lang.Integer]=>

}
@Jamil,我相信
Seq[java.lang.Integer]
只是一个语法错误。我相信编译器将
java.lang.Integer
视为一个标识符,它们不能有点。你可以通过在反引号中包围
java.lang.Integer
来证明这一点-它将编译,但你仍然会得到与普通
Integer
相同的擦除警告。我同意这个错误是有误导性的,但考虑到@Frank无论如何都无法真正做到这一点也不奇怪。
java.lang.Integer
是一种类型而不是变量。此外,当您使用构造函数模式、元组或序列等时,Scala绑定到变量。奇怪的是,如果我使用别名
type myint=java.lang.Integer
Scala不会complain@Jamil,我知道它是一个类型,这就是关键所在-编译器期望一个变量,并试图将
java.lang.Integer
解释为一个变量,但它不是一个有效的变量名,因为其中有点。哇。我今天找到了这个问题,最终找到了这个问题。我不知道什么是“类型变量模式”甚至存在于Scala中。在SLS中还有什么对我隐藏的…?一些复活节彩蛋只在1/4和复活节时激活。我在上开始了一个线程,现在有一张票在上;Martin Odersky说这是一个解析器错误