Scala不会与java.lang.String和Case Class进行模式匹配

Ste*_*fan 10 types scala pattern-matching case-class

你好同胞Scala程序员

我已经和Scala合作了一个月,但是我对一些基本的东西有问题,我希望你能帮助我.

case class PersonClass(name: String, age: Int)

object CaseTester {
def main(args:Array[String])
 {
  val string = "hej"
  string match {
    case e:String => println(string)
    case PersonClass => println(string)
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我得到错误:

pattern type is incompatible with expected type;
found   : object PersonClass
required: java.lang.String
case PersonClass => println(string)
Run Code Online (Sandbox Code Playgroud)

如果我然后将模式匹配中的第二行更改为以下内容:

case e:PersonClass => println(string)
Run Code Online (Sandbox Code Playgroud)

然后我得到错误:

error: scrutinee is incompatible with pattern type;
found   : PersonClass
required: java.lang.String
case e:PersonClass => println(string)
Run Code Online (Sandbox Code Playgroud)

但是,如果我将字符串定义更改为以下内容,则在两种情况下都可以正常编译.

val string:AnyRef = "hej"
Run Code Online (Sandbox Code Playgroud)

San*_*ozi 22

推断的字符串类型是String.在声明val后就知道了.

正如我们在模式匹配期间已经知道的那样,匹配不是字符串的模式(如您的PersonClass)是没有意义的,因为它们永远不会匹配.这就是"模式类型与预期类型不兼容;发现:对象PersonClass必需:java.lang.String case PersonClass => println(string)"错误意味着:我们期望一个模式是String的子类,但找到了一些东西( PersonClass)哪个不是.

当您强制AnyRef类型时,情况会发生变化.编译器会将字符串视为Anyref,因此扩展AnyRef的模式可能会匹配.PersonClass是AnyRef,因此您不会收到错误.


Tho*_*ung 9

如果您已经有String类型的对象,它将永远不会匹配PersonClass类型.它实际上是一个功能,编译器不会让这些匹配永远不会成功.

使用Any类型,您只需关闭类型检查.它与此定义不匹配,但编译器无法捕获此问题.


Rex*_*err 5

我假设你正在尝试测试别的东西,但编译器太聪明了,不能让你.

也许你想要这样的东西:

object Test {
  case class Person(name: String, age: Int) { }
  def myPrint(ar: AnyRef) {
    ar match {
      case s: String => println(s)
      case Person(name, age) => println("My name is "+name)
      case _ => println("I am a mystery!")
    }
  }
  def test = {
    myPrint("Hello, World")
    myPrint(Person("John Doe",40))
    myPrint(5)
  }
}
Run Code Online (Sandbox Code Playgroud)

但正如其他人所指出的,如果你不真正需要检查的其他类型,编译器会抱怨你在做什么是没有意义的.也是一件好事:如果您没有编写测试,则可能会遇到难以调试的运行时错误.