scala中的模式匹配在def中起作用,否则不起作用

scala中的模式匹配在def中起作用,否则不起作用,scala,pattern-matching,Scala,Pattern Matching,在下面的第一个代码段中,case语句是在函数中定义的,它按预期工作 代码片段1 输出 得到1和2 得到1,2和3 下面的情况不在函数中,但在其他方面与上面的情况非常相似。它给出了一个错误。我理解这个错误,但我不理解的是为什么我得到的是下面的错误而不是上面的错误 代码片段2 输出 :14:错误:无法将构造函数实例化为预期类型; 发现:(T1,T2) 必需:(Int,Int,Int) case(a,b)=>s“got$a和$b”scala模式匹配的这种行为的原因在于类型系统。Scala有一个非常强大

在下面的第一个代码段中,case语句是在函数中定义的,它按预期工作

代码片段1 输出 得到1和2

得到1,2和3

下面的情况不在函数中,但在其他方面与上面的情况非常相似。它给出了一个错误。我理解这个错误,但我不理解的是为什么我得到的是下面的错误而不是上面的错误

代码片段2 输出 :14:错误:无法将构造函数实例化为预期类型; 发现:(T1,T2) 必需:(Int,Int,Int)
case(a,b)=>s“got$a和$b”

scala模式匹配的这种行为的原因在于类型系统。Scala有一个非常强大的类型系统,它允许高类型安全性并在编译时捕获错误。如果您声明一个函数具有参数而不是Any,它也将抛出相同的错误

例如:-

def echoWhatYouGaveMe(x: (Int, Int)): String = x match {

  case (a, b) => s"got $a and $b"
  case (a, b, c) => s"got $a, $b, and $c"
  case _ => "Unknown"
}

echoWhatYouGaveMe((1,2))
你会得到一个错误声明

Error:(4, 9) constructor cannot be instantiated to expected type;
 found   : (T1, T2, T3)
 required: (Int, Int)
  case (a, b, c) => s"got $a, $b, and $c"
       ^
如果修改val myTuple并显式将其类型设置为Any,则它将允许您执行模式匹配

val myTuple: Any = (1, 2, 3)

val toPrint = myTuple match {
  case (a, b, c) => s"got $a, $b, and $c"
  case (a, b) => s"got $a and $b"
  case _ => s"Unknown data"
}
你会得到这样的输出

myTuple: Any = (1,2,3)

toPrint: String = got 1, 2, and 3

scala模式匹配出现这种行为的原因在于类型系统。Scala有一个非常强大的类型系统,它允许高类型安全性并在编译时捕获错误。如果您声明一个函数具有参数而不是Any,它也将抛出相同的错误

例如:-

def echoWhatYouGaveMe(x: (Int, Int)): String = x match {

  case (a, b) => s"got $a and $b"
  case (a, b, c) => s"got $a, $b, and $c"
  case _ => "Unknown"
}

echoWhatYouGaveMe((1,2))
你会得到一个错误声明

Error:(4, 9) constructor cannot be instantiated to expected type;
 found   : (T1, T2, T3)
 required: (Int, Int)
  case (a, b, c) => s"got $a, $b, and $c"
       ^
如果修改val myTuple并显式将其类型设置为Any,则它将允许您执行模式匹配

val myTuple: Any = (1, 2, 3)

val toPrint = myTuple match {
  case (a, b, c) => s"got $a, $b, and $c"
  case (a, b) => s"got $a and $b"
  case _ => s"Unknown data"
}
你会得到这样的输出

myTuple: Any = (1,2,3)

toPrint: String = got 1, 2, and 3
当你写作时

val myTuple = (1, 2, 3)
myTuple
的类型被推断为
(Int,Int,Int)
。因此,当您匹配它时,所有模式都必须与该类型兼容,即需要有与该模式匹配的该类型的值。否则,该模式是无用的,也可以删除<代码>案例(a,b)就是这样一个无用的模式

在代码片段1中,模式不是无用的,因为它在您编写代码时与
Any
兼容

val myTuple = (1, 2, 3)
myTuple
的类型被推断为
(Int,Int,Int)
。因此,当您匹配它时,所有模式都必须与该类型兼容,即需要有与该模式匹配的该类型的值。否则,该模式是无用的,也可以删除<代码>案例(a,b)就是这样一个无用的模式


在代码段1中,模式不是无用的,因为它与
代码段2中的
Any

兼容
将定义更改为
val-toPrint=(s:Any)=>s-match{
然后可以将
myTuple
作为
toPrint(myTuple)
传递到
代码段2中的
将定义更改为
val-toPrint=(s:Any)=>s match{
然后您可以将
myTuple
作为
toPrint(myTuple)
@subwrajit Bhattacharya希望这能回答您的问题。@subwrajit Bhattacharya希望这能回答您的问题。