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

发布于 2024-08-29 07:04:44 字数 907 浏览 6 评论 0原文

大家好,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)
  }
 }
}

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

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

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

case e:PersonClass => println(string)

然后我收到错误:

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

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

val string:AnyRef = "hej"

Hello fellow Scala Programmers

I have been working with Scala for some month now, however I have a problem with some properly basic stuff, I am hoping you will help my out with it.

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)
  }
 }
}

When I am doing like this I get error:

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

And if I then change the second line in the pattern matching to the following:

case e:PersonClass => println(string)

I then get the error:

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

However if I change the string definition to the following it compiles fine in both cases.

val string:AnyRef = "hej"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

治碍 2024-09-05 07:04:44

推断的字符串类型是 String。这是在 val 声明后已知的。

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

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

The inferred type of string is String. That is known after the declaration of the val.

As we already know it during pattern matching it doesn't make sense to match patterns that are not Strings (like your PersonClass), as they will never match. That's what the "pattern type is incompatible with expected type; found : object PersonClass required: java.lang.String case PersonClass => println(string)" error means: we expect a pattern that is a subclass of String, but found something (PersonClass) which is not.

When you force the type AnyRef the situation changes. The compiler will treat string as Anyref, so patterns that extend AnyRef might match. PersonClass is AnyRef, so you don't get error.

放肆 2024-09-05 07:04:44

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

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

If you already have an object of type String it will never match a type PersonClass. It's actually a feature that the compiler does you not let do these matches that will never succeed.

With the Any type you are simply turning the type check off. It won't match with this definition but the compiler can't catch this problem.

没有心的人 2024-09-05 07:04:44

我假设您正在尝试测试其他东西,但编译器太聪明了,不允许您这样做。

也许您想要这样的东西:

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)
  }
}

但正如其他人指出的那样,如果您实际上不需要检查其他类型,编译器会抱怨您所做的事情毫无意义。这也是一件好事:如果您没有编写测试,则可能会遇到难以调试的运行时错误。

I assume you're trying to test something else, but the compiler is too smart to let you.

Maybe you want something like this:

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)
  }
}

but as others have pointed out, if you don't actually need to check for the other types, the compiler will complain that what you're doing is pointless. A good thing, too: if you weren't writing a test, you might have a hard-to-debug runtime error.

谢绝鈎搭 2024-09-05 07:04:44
object ws {

case class PersonClass(name:String,age: Int)
val p=new PersonClass("ach",25)                    

  def string(x: Any) = x match {
    case x:String => println(x)
    case x:PersonClass => println(p.name +" "+p.age)
   }                                              

     string("aa")                                 //> aa
     string(p)                                    //> ach 25

}
object ws {

case class PersonClass(name:String,age: Int)
val p=new PersonClass("ach",25)                    

  def string(x: Any) = x match {
    case x:String => println(x)
    case x:PersonClass => println(p.name +" "+p.age)
   }                                              

     string("aa")                                 //> aa
     string(p)                                    //> ach 25

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文