Scala error matching patterns when returning null in a tuple

Below are two snippets, I canโ€™t understand why one is successful, and the other is runtime exception.

Snippet1:

val str = "HELP"

val perfectTuple: (String, String) = str match {
    case "NO-HELP" => ("First Help", "Second Help")
    case "OTHER-HELP" => ("I won't Help!", "Even,I won't Help!")
    case "HELP" => (null,"Single Help")
    case _ => throw new NoSuchMethodException

  }

Snippet2:

val str = "HELP"

val (firstPart:String, secondPart:String) = str match {
  case "NO-HELP" => ("First Help", "Second Help")
  case "OTHER-HELP" => ("I won't Help!", "Even,I won't Help!")
  case "HELP" => (null,"Single Help")
  case _ => throw new NoSuchMethodException
}

============================

There are very few differences between the two fragments. One saves the returned tuple to a "perfectTuple" value of type tuple2, and this one succeeds.

The other retrieves the values โ€‹โ€‹from tuple 2 and stores them in string values โ€‹โ€‹and throws a run time of 'scala.matchError'.

Is this a bug in scala?

I tried this on scala 2.10.5 and 2.11.7

Thanks in advance.

==============

another scenario where I can assign zero to a string from pattern matching, and this works absolutely perfectly: Snippet3:

val str = "HELP"

val assignNullToString: String = str match {

    case "NO-HELP" => "ONE"
    case "OTHER-HELP" => "TWO"
    case "HELP" => null
    case _ => throw new NoSuchMethodException
}          

, , , null String, , - Tuple? Snippet 2, Snippet 1 .

+4
2

, unapply of case class Tuple2.

Tuple2.unapply, , - .

null.

val str: Any = null

str match {
  case _: String => "yay"
  case other => "damn"
}
|-> res1: String = damn

:

val str = "HELP"

val (firstPart:String, secondPart:String) = str match {
  case "NO-HELP" => ("First Help", "Second Help")
  case "OTHER-HELP" => ("I won't Help!", "Even,I won't Help!")
  case "HELP" => (null,"Single Help")
  case _ => throw new NoSuchMethodException
}

, :

val tuple: (String, String) = str match {
  case "NO-HELP" => ("First Help", "Second Help")
  case "OTHER-HELP" => ("I won't Help!", "Even,I won't Help!")
  case "HELP" => (null,"Single Help")
  case _ => throw new NoSuchMethodException
}

unapply Tuple2. :

def unapply[A, B](tuple: Tuple2[_, _]): Option[(A, B)]

, ! ,

val (first: String, second: String) = tuple

Tuple2.unapply [String, String], , (String, String).

Option[(String, String)], unapply .

, - Tuple2 , :

object Tuple2 {
  def apply[A, B](_1: A, _2: B): Tuple2[A, B] = new Tuple2(_1, _2)

def unapply[A, B](tuple: Tuple2[_, _]): Option[(A, B)] = {
  val a: Option[A] = tuple._1 match { case a: A => Some(a) }
  val b: Option[B] = tuple._2 match { case b: B => Some(b) }

  a.zip(b).headOption
}

, MatchError:

  val a: Option[A] = tuple._1 match { case a: A => Some(a) }

, Tuple2, , , .

, :

val str = "HELP"

val (firstPart, secondPart) = str match {
  case "NO-HELP" => ("First Help", "Second Help")
  case "OTHER-HELP" => ("I won't Help!", "Even,I won't Help!")
  case "HELP" => (null,"Single Help")
  case _ => throw new NoSuchMethodException
}

, , , .

2

, vals , .

, .

val foo = ("lorem", 2)
val (lorem: String, bad: String) = foo // fail 

case class Bar(name: String, age: Option[Int])
val bar = Bar("Sam", None)
val Bar(name, Some(age)) = bar // fail
+5

"Help" , , null firstPart, String. . .

scala> val (firstPart: String, secondPart: String) = ("foo", "bar")
firstPart: String = foo
secondPart: String = bar

scala> val (firstPart: String, secondPart: String) = (null, "bar")
<console>:10: error: pattern type is incompatible with expected type;
 found   : String
 required: Null
       val (firstPart: String, secondPart: String) = (null, "bar")

null String, .

0

Source: https://habr.com/ru/post/1629924/


All Articles