【发布时间】:2016-10-04 19:48:32
【问题描述】:
为什么 Scala 中的模式匹配适用于 String 和 AnyVals,例如 Int?
通常我们会看到类似Case classes 或Extractors...
【问题讨论】:
为什么 Scala 中的模式匹配适用于 String 和 AnyVals,例如 Int?
通常我们会看到类似Case classes 或Extractors...
【问题讨论】:
提取器和案例类仅用于13 kinds of patterns in Scala 中的两个,分别是“提取器模式”和“构造器模式”。您不能在这种模式中使用Int 或String (case String(x))。但是您可以将它们用于其他类型:
键入的模式,如case x: String。在这种情况下,String 没有什么特别之处,你可以对任何类做同样的事情(但 Int 和其他原语有一些特别之处:case x: Int 实际上检查接收到的对象是否是 java.lang.Integer 在大多数情况下例)。
文字模式,如case 0 或case ""。同样,字符串没什么特别的,这适用于所有文字。
【讨论】:
java.lang.String 富含 scala.collection.immutable.StringOps (http://www.scala-lang.org/api/2.11.8/#scala.collection.immutable.StringOps),其中混合了 scala.collection.immutable.StringLike (http://www.scala-lang.org/api/2.11.8/#scala.collection.immutable.StringLike)。您可以在其中找到补充方法,例如 apply。
String 也有点特殊,您可以将其转换为Chars 的列表,然后使用List 提取器,然后在String 上使用case List(a,b) 或case x:xs,请记住a 和 b 将是 Chars; x: Char 和 xs: List[Char]
所有原始类型都有 Rich* 类(例如 scala.runtime.RichBoolean、scala.runtime.RichByte)。
值类机制用于丰富上述所有类型 (http://docs.scala-lang.org/overviews/core/value-classes.html)。在编译时它们有一个包装器类型,例如 RichBoolean 或 RichInt,但在运行时它们是纯布尔或 Int 类型。这样可以避免创建运行时对象的开销。
【讨论】:
toList。老实说,我认为它无需额外的努力就可以工作%)。我将编辑答案。
List[Char] 还是相当慢,而且生成的列表比String 占用更多的内存很多。 很多最好使用toSeq(或隐式转换为Seq[Char]),它只会创建一个小的包装对象,并使用Seq-specific(但不是List-specific)方法和匹配器。
val x: Any = 5
def f[T](v: T) = v match {
case _: Int => "Int"
case _: String => "String"
case _ => "Unknown"
}
【讨论】:
您不必在类中定义unapply 即可在switch/case 样式匹配中使用该类。 unapply是用来解构对象的,所以如果你想匹配List-style(case x:xs)中的switch,你应该使用unapply/unapplySeq。这里很好的例子是正则表达式,它们是由字符串构造的——"something".r(最后注意.r)。
【讨论】: