Scala не будет соответствовать шаблону с java.lang.String и Case Class - PullRequest
10 голосов
/ 16 апреля 2010

Здравствуйте, программисты 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"

Ответы [ 4 ]

22 голосов
/ 16 апреля 2010

Предполагаемый тип строки - String. Это известно после провозглашения вал.

Как мы уже знаем, при сопоставлении с образцом нет смысла сопоставлять шаблоны, которые не являются строками (например, ваш PersonClass), так как они никогда не будут совпадать. Вот что означает «тип шаблона несовместим с ожидаемым типом; найдено: объект PersonClass required: java.lang.String case PersonClass => println (string)» ошибка означает: мы ожидаем, что шаблон является подклассом String, но нашел что-то ( PersonClass), которого нет.

Когда вы вводите тип AnyRef, ситуация меняется. Компилятор будет обрабатывать строку как Anyref, поэтому шаблоны, расширяющие AnyRef, могут совпадать. PersonClass - это AnyRef, поэтому вы не получите ошибку.

9 голосов
/ 16 апреля 2010

Если у вас уже есть объект типа String, он никогда не будет соответствовать типу PersonClass. Это на самом деле особенность, которую компилятор не позволяет делать таким совпадениям, которые никогда не будут успешными.

С типом Any вы просто отключаете проверку типа. Это не будет соответствовать этому определению, но компилятор не может поймать эту проблему.

5 голосов
/ 16 апреля 2010

Полагаю, вы пытаетесь проверить что-то еще, но компилятор слишком умен, чтобы позволить вам.

Может быть, вы хотите что-то вроде этого:

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

но, как уже отмечали другие, если вам не нужно на самом деле проверять другие типы, компилятор будет жаловаться на то, что вы делаете бессмысленно. Хорошая вещь: если вы не писали тест, у вас может быть трудно отлаживаемая ошибка времени выполнения.

0 голосов
/ 27 декабря 2013
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

}
...