Привет Программисты товарища 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"
Предполагаемый тип строки - String. Это известно после объявления val.
Как мы уже знаем, во время сопоставления с образцом нет смысла сопоставлять образцы, которые не являются строками (например, ваш PersonClass), поскольку они никогда не будут совпадать. Вот что "тип шаблона несовместим с ожидаемым типом; найдено: объект PersonClass required: java.lang.String case PersonClass => println (string)" означает ошибку: мы ожидаем шаблон, который является подклассом String, но что-то обнаружил ( PersonClass), которого нет.
Когда вы вызываете тип AnyRef, ситуация меняется. Компилятор будет рассматривать строку как Anyref, поэтому шаблоны, расширяющие AnyRef, могут совпадать. PersonClass - это AnyRef, поэтому вы не получите ошибки.
Я полагаю, вы пытаетесь проверить что-то еще, но компилятор слишком умен, чтобы вам это позволить.
Может быть, вам нужно что-то вроде этого:
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)
}
}
но, как указывали другие, если вам на самом деле не нужно проверять другие типы, компилятор будет жаловаться на то, что вы делаете бессмысленно. Также хорошо: если бы вы не писали тест, у вас могла бы возникнуть ошибка времени выполнения, которую трудно отладить.
Если у вас уже есть объект типа String, он никогда не будет соответствовать типу PersonClass. На самом деле компилятор не позволяет вам выполнять такие совпадения, которые никогда не увенчаются успехом.
При выборе типа Any вы просто отключаете проверку типа. Это не соответствует этому определению, но компилятор не может решить эту проблему.