Scala:在类型模式匹配期间转发参考错误

时间:2015-10-29 10:27:52

标签: scala compiler-errors forward-reference

我希望了解以下Scala代码生成的编译时错误:

class MyClass {
    def determineType(x:Any):String = {
        x match {
            case Int => "It's an int."
            case Float => "It's a Float."
            case CIn  => "It's a CIn without a specifier."
            case c:CIn => "It's a CIn with a specifier."
            case DIn=> "It's a DIn without a specifier." // Error:Cannot resolve symbol DIn
            case d:DIn=> "It's a DIn with a specifier."
            case _ => "It's something else."
        }
    }
    case class CIn()
    class DIn
} // End class definition

def determineType(x:Any):String = {
    x match {
        case Int => "It's an int"
        case Float => "It's a Float"
        case COut  => "It's a COut without a specifier." // Error: Wrong forward reference
        case c:COut => "It's a COut with a specifier."
        case DOut=> "It's a DOut without a specifier." // Error: Cannot resolve symbol DOut.
        case d:DOut=> "It's a DOut with a specifier."
        case _ => "It's something else."
    }
}

case class COut()
class DOut()

determineType中的MyClass版本中,case class CIn以及常规class DIn都在determineType之后定义并声明}。尝试匹配没有说明符变量的DIn时会生成符号解析错误。

在脚本范围内,我们同样定义了case class Cout和常规class DOut。在determineType的脚本范围版本中,我们有两个不同的错误。第一个是在没有说明符的情况下引用case class类型(Cout)时生成的,它显示“错误的前向引用”。第二个是在引用不带说明符的常规class类型(DOut)时生成的,它是符号解析错误。

我是该语言的新手,因此不确定为什么在case语句中包含说明符会影响前向引用的处理方式。

1 个答案:

答案 0 :(得分:2)

如果你写了一个匹配条款case Foo =>,你不匹配类型(或类)Foo,而是 {{1 }}。因此,Foo 匹配整数值,而case Int =>不起作用,因为没有值(或对象)case DIn =>

以下作品:

DIn

如果要匹配类的实例,则需要匹配子句val Foo = 1 object Bar def testVal(x: Any) = x match { case Foo => "it's Foo" case Bar => "it's Bar" case _ => "none of the above" } testVal(1) // Foo! testVal(Bar) // Bar testVal(Foo + 1) // none case b: Baz =>(如果您不想将实例绑定到值)。对于案例类,您可以进一步使用自动提供的提取器,因此使用case _: Baz您也可以匹配为case class Baz()。当case Baz() =>包含由此提取的参数时,这通常更有意义:

Baz

案例类还为您提供了一个伴随case class Baz(i: Int) def testType(x: Any) = x match { case Baz(3) => "Baz with argument 3" case b: Baz => "Baz with argument other than 3" case Baz => "Baz companion!" case _ => "none of the above" } testType(Baz) // companion object! testType(Baz(3)) testType(Baz(4)) ,因此您可以使用object实际匹配该对象。 case Baz =>是一种价值。

最后,我不知道您使用的是哪个Scala版本,但在常规的当前Scala中,您不能忽略object定义的RHS上的match关键字:

determineType
def determineType(x: Any): String = {
  case _ => "anything"
}

你必须写:

<console>:53: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: String
          def determineType(x: Any): String = {
                                              ^