类型模式匹配为什么变量是必须的
Type pattern match why a variable is a must
我正在阅读 "Scala for Impatient 2nd" 第 14.4 节,我对上下文感到困惑:
You can match on the type of an expression, for example :
obj match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
}
When you match against a type, you must supply a variable name.
Otherwise, you match the object :
obj match {
case _:BigInt => Int.MaxValue // Matches any object of type BigInt
case BigInt => -1 // Matches the BigInt object of type Class
}
我感到困惑的是如何理解作为 expression
请求的 obj
:
如果我测试如下:
val x = 121
val obj : Any = x
obj == 121 // true
obj match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
} // res133: Int = 121
但是,如果我只是将整数值分配给 obj
,编译器会抛出错误:
val obj2 = 121
obj2 == 121 // true
obj2 match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
} // <console>:22: error : scrutinee is incompatible with pattern type;
found : String
required : Int
case s : String => Integer.parseInt(s)
^
<console>:23: error : scrutinee is incompatible with pattern type;
found : BigInt
required : Int
case _ : BigInt => Int.MaxValue
^
唯一的区别是前一个例子我用另一个变量赋值obj
,而后一个例子我用一个整数值赋值obj
。为什么后一个例子会出现编译错误?
问题更新:我理解 "compiler knows that obj2
is Int
",但是,我认为这就是 match
表达式的作用,因为 obj2
是 Int
并且它遇到了第一个 match
子句 case x:Int => x
因此匹配成功并且整个匹配表达式完成。我认为这应该和前面的例子完全一样,唯一的区别是这两个变量是 Any
和 Int
类型,但是它们都匹配了第一个匹配子句并且它们都应该是正确编译。
根据本书第 14.4 节 "In Scala, this (type pattern) match is preferred to using the isInstanceOf
operator",我认为使用类型模式是一种识别对象类型的方法。如果我们知道对象类型,那么 "type pattern" 有什么用?
第二个问题是我对下面的上下文感到困惑。如何理解 "object of type BigInt" v.s "BigInt object of type Class" ? "type Class
" 与 java generic/reflection 概念相关吗?
obj match {
case _:BigInt => Int.MaxValue // Matches any object of type BigInt
case BigInt => -1 // Matches the BigInt object of type Class
}
谢谢!
由于类型推断,第二个赋值缺少类型归属
val obj2 = 121
使 obj2
成为 Int
,而不是
val obj : Any = x
这使它成为 Any
。
在第二种情况下,编译器知道 obj2
是 Int
,因此它知道 String
或 BigInt
的匹配不可能成功.
这里在编译时已知的和在 运行 时已知的是有区别的。您有以下代码:
val x = 121
val obj: Any = x
在 运行 时,x
和 obj
都是 Int
并且将匹配您的 match
表达式中的第一个案例。
在编译时,编译器知道 x
是 Int
,因此它知道没有必要测试 String
或 BigInt
。它所知道的 obj
是 Any
,因此可以检查 String
、BigInt
或任何其他类型。
现在在这种情况下,很明显编译器可以计算出 obj
实际上是 Int
,但在一般情况下这是不可能的。编译器没有关于类型推断的复杂规则,而是使用程序员为值 Any
提供的类型。因此它假定 obj
可能是 String
或 BigInt
即使在这种情况下从代码中可以明显看出它不是。
How to understand "object of type BigInt" v.s "BigInt object of type Class" ? is "type Class" related to java generic/reflection concept ?
这只是书中的一个错误。 BigInt
模式(即 case BigInt => ...
)匹配声明为
的 companion object
object BigInt { ... }
在代码中。它是不是类型Class
;它的类型 is written as BigInt.type
,但很少有用。
所以如果你写
val x: Any = BigInt
x match {
case _: BigInt => // doesn't match
case BigInt => // matches
}
而 val x: Any = new BigInt(...)
将匹配第一个而不是第二个。
我正在阅读 "Scala for Impatient 2nd" 第 14.4 节,我对上下文感到困惑:
You can match on the type of an expression, for example :
obj match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
}
When you match against a type, you must supply a variable name. Otherwise, you match the object :
obj match {
case _:BigInt => Int.MaxValue // Matches any object of type BigInt
case BigInt => -1 // Matches the BigInt object of type Class
}
我感到困惑的是如何理解作为 expression
请求的 obj
:
如果我测试如下:
val x = 121
val obj : Any = x
obj == 121 // true
obj match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
} // res133: Int = 121
但是,如果我只是将整数值分配给 obj
,编译器会抛出错误:
val obj2 = 121
obj2 == 121 // true
obj2 match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
} // <console>:22: error : scrutinee is incompatible with pattern type;
found : String
required : Int
case s : String => Integer.parseInt(s)
^
<console>:23: error : scrutinee is incompatible with pattern type;
found : BigInt
required : Int
case _ : BigInt => Int.MaxValue
^
唯一的区别是前一个例子我用另一个变量赋值obj
,而后一个例子我用一个整数值赋值obj
。为什么后一个例子会出现编译错误?
问题更新:我理解 "compiler knows that obj2
is Int
",但是,我认为这就是 match
表达式的作用,因为 obj2
是 Int
并且它遇到了第一个 match
子句 case x:Int => x
因此匹配成功并且整个匹配表达式完成。我认为这应该和前面的例子完全一样,唯一的区别是这两个变量是 Any
和 Int
类型,但是它们都匹配了第一个匹配子句并且它们都应该是正确编译。
根据本书第 14.4 节 "In Scala, this (type pattern) match is preferred to using the isInstanceOf
operator",我认为使用类型模式是一种识别对象类型的方法。如果我们知道对象类型,那么 "type pattern" 有什么用?
第二个问题是我对下面的上下文感到困惑。如何理解 "object of type BigInt" v.s "BigInt object of type Class" ? "type Class
" 与 java generic/reflection 概念相关吗?
obj match {
case _:BigInt => Int.MaxValue // Matches any object of type BigInt
case BigInt => -1 // Matches the BigInt object of type Class
}
谢谢!
由于类型推断,第二个赋值缺少类型归属
val obj2 = 121
使 obj2
成为 Int
,而不是
val obj : Any = x
这使它成为 Any
。
在第二种情况下,编译器知道 obj2
是 Int
,因此它知道 String
或 BigInt
的匹配不可能成功.
这里在编译时已知的和在 运行 时已知的是有区别的。您有以下代码:
val x = 121
val obj: Any = x
在 运行 时,x
和 obj
都是 Int
并且将匹配您的 match
表达式中的第一个案例。
在编译时,编译器知道 x
是 Int
,因此它知道没有必要测试 String
或 BigInt
。它所知道的 obj
是 Any
,因此可以检查 String
、BigInt
或任何其他类型。
现在在这种情况下,很明显编译器可以计算出 obj
实际上是 Int
,但在一般情况下这是不可能的。编译器没有关于类型推断的复杂规则,而是使用程序员为值 Any
提供的类型。因此它假定 obj
可能是 String
或 BigInt
即使在这种情况下从代码中可以明显看出它不是。
How to understand "object of type BigInt" v.s "BigInt object of type Class" ? is "type Class" related to java generic/reflection concept ?
这只是书中的一个错误。 BigInt
模式(即 case BigInt => ...
)匹配声明为
object BigInt { ... }
在代码中。它是不是类型Class
;它的类型 is written as BigInt.type
,但很少有用。
所以如果你写
val x: Any = BigInt
x match {
case _: BigInt => // doesn't match
case BigInt => // matches
}
而 val x: Any = new BigInt(...)
将匹配第一个而不是第二个。