编写如下代码:

  1. object MatchTest {
  2. def foo(a : Any) : String =
  3. {
  4. a match {
  5. case 1 => "int:1"
  6. case x : Int if (x > 50) => "int(>50):" + x
  7. case x : Int => "int:" + x
  8. case (x, y) => "tuple:" + x + "," + y
  9. case h :: t => "list:" + h + "," + t
  10. case Array(90) => "array:90"
  11. case Array(90, x) => "array:90," + x
  12. case _ => ":("
  13. }
  14. }
  15. def main(args : Array[String]) {
  16. println(foo(1))
  17. println(foo(51))
  18. println(foo(49))
  19. println(foo((1, 2)))
  20. println(foo((1, 2, 3)))
  21. println(foo((3 -> 4)))
  22. println(foo(List(80, 81)))
  23. println(foo(Array(90, 91)))
  24. }
  25. }

通过class代码反编译,看到java源代码如下:

  1. public String foo(Object a)
  2. {
  3. int i = 0; int j = 0;
  4. Object localObject1 = a;
  5. String str;
  6. if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(1), localObject1)) { str = "int:1"; } else {
  7. if ((localObject1 instanceof Integer)) { i = 1; j = BoxesRunTime.unboxToInt(localObject1); if (j > 50) { str = new StringBuilder().append("int(>50):").append(BoxesRunTime.boxToInteger(j)).toString(); break label464;
  8. }
  9. }
  10. if (i != 0)
  11. {
  12. str = new StringBuilder().append("int:").append(BoxesRunTime.boxToInteger(j)).toString();
  13. } else if ((localObject1 instanceof Tuple2)) { Tuple2 localTuple2 = (Tuple2)localObject1; Object x = localTuple2._1(); Object y = localTuple2._2(); str = new StringBuilder().append("tuple:").append(x).append(",").append(y).toString();
  14. } else if ((localObject1 instanceof .colon.colon)) { .colon.colon localcolon = (.colon.colon)localObject1; Object h = localcolon.head(); List t = localcolon.tl$1(); str = new StringBuilder().append("list:").append(h).append(",").append(t).toString(); } else {
  15. if (ScalaRunTime..MODULE$.isArray(localObject1, 1)) { Object localObject2 = localObject1; Option localOption1 = Array..MODULE$.unapplySeq(localObject2); if ((!localOption1.isEmpty()) && (localOption1.get() != null) && (((SeqLike)localOption1.get()).lengthCompare(1) == 0)) { Object localObject3 = ((SeqLike)localOption1.get()).apply(0); if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(90), localObject3)) { str = "array:90"; break label464; } } }
  16. if (ScalaRunTime..MODULE$.isArray(localObject1, 1)) { Object localObject4 = localObject1; Option localOption2 = Array..MODULE$.unapplySeq(localObject4); if ((!localOption2.isEmpty()) && (localOption2.get() != null) && (((SeqLike)localOption2.get()).lengthCompare(2) == 0)) { Object localObject5 = ((SeqLike)localOption2.get()).apply(0); Object x = ((SeqLike)localOption2.get()).apply(1); if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(90), localObject5)) { str = new StringBuilder().append("array:90,").append(x).toString(); break label464; } } }
  17. str = ":(";
  18. }
  19. }
  20. label464: return str;
  21. }

对于h::t的写法,其解释是:

  • 它其实是个中置表示法,等价于::(h,t)
  • ::是一个样例类!(java里该写的类名叫.colon.colon)

再试一个简单的自定义object的例子:

  1. object Email {
  2. def unapply(str : String) : Option[(String, String)] = {
  3. val parts = str split "@"
  4. if (parts.length == 2) Some(parts(0), parts(1)) else None
  5. }
  6. def main(args : Array[String]) {
  7. val str = "bluejoe2008@gmail.com"
  8. str match {
  9. case Email(username, host) => println(s"username: $username host: $host");
  10. case _ => println("this is not an email address ");
  11. }
  12. }
  13. }

反编译代码:

  1. public void main(String[] args) {
  2. String str = "bluejoe2008@gmail.com";
  3. String str1 = str;
  4. Option localOption = unapply(str1);
  5. BoxedUnit localBoxedUnit;
  6. if (localOption.isEmpty()) {
  7. Predef..MODULE$.println("this is not an email address "); localBoxedUnit = BoxedUnit.UNIT;
  8. }
  9. else
  10. {
  11. String username = (String)((Tuple2)localOption
  12. .get())._1(); String host = (String)((Tuple2)localOption
  13. .get())._2(); Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "username: ", " host: ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { username, host }))); localBoxedUnit = BoxedUnit.UNIT;
  14. }
  15. }

如下内容摘录于http://cuipengfei.me/blog/2014/06/14/scala-unapply-method/

unapplySeq和unapply的作用很是类似,例如这样:

  1. object Names {
  2. def unapplySeq(str: String): Option[Seq[String]] = {
  3. if (str.contains(",")) Some(str.split(","))
  4. else None
  5. }
  6. }

这里定义了一个unapplySeq方法,用逗号作为分隔符来把字符串拆开。然后我们可以这样应用它:

  1. val namesString = "xiao ming,xiao hong,tom"
  2. namesString match {
  3. case Names(first, second, third) => {
  4. println("the string contains three people's names")
  5. println(s"$first $second $third")
  6. }
  7. case _ => println("nothing matched")
  8. }

与上面的例子很是类似,不过编译器在这里替我们做的事情更多了:

  • 调用unapplySeq,传入namesString
  • 接收返回值并判断返回值是None,还是Some
  • 如果是Some,则将其解开
  • 判断解开之后得到的sequence中的元素的个数是否是三个
  • 如果是三个,则把三个元素分别取出,赋值给first,second和third

scala学习笔记:match与unapply()的更多相关文章

  1. Scala学习笔记--提取器unapply

    提取器就是一个带有unapply方法的对象.你可以把unapply方法当做是伴生对象中apply方法的反向操作. apply方法接收构造参数,然后将他们变成对象. 而unapply方法接受一个对象,然 ...

  2. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  3. Scala学习笔记及与Java不同之处总结-从Java开发者角度

    Scala与Java具有很多相似之处,但又有很多不同.这里主要从一个Java开发者的角度,总结在使用Scala的过程中所面临的一些思维转变. 这里仅仅是总结了部分两种语言在开发过程中的不同,以后会陆续 ...

  4. Scala学习笔记之:tuple、array、Map

    [TOC] 本文<快学Scala>的笔记 tuple学习笔记 tuple的定义 对偶是元组(tuple)的最简单形态--元组是不同类型的值的聚集. 元组的值是通过将单个值包含在圆括号中构成 ...

  5. 机器学习(三)--- scala学习笔记

    Scala是一门多范式的编程语言,一种类似Java的编程语言,设计初衷是实现可伸缩的语言.并集成面向对象编程和函数式编程的各种特性. Spark是UC Berkeley AMP lab所开源的类Had ...

  6. scala学习笔记:match表达式

    写了一个超级长的表达式,估计不是最简洁的: scala> def foo(ch:Any)=ch match { case true=>"male";case false ...

  7. 【大数据】Scala学习笔记

    第 1 章 scala的概述1 1.1 学习sdala的原因 1 1.2 Scala语言诞生小故事 1 1.3 Scala 和 Java  以及 jvm 的关系分析图 2 1.4 Scala语言的特点 ...

  8. 原创:Scala学习笔记(不断更新)

    Scala是一种函数式语言和面向对象语言结合的新语言,本笔记中就零散记下学习scala的一些心得,主要侧重函数式编程方面. 1. 以递归为核心控制结构. 实现循环处理的方式有三种:goto,for/w ...

  9. Scala学习笔记(详细)

    第2章 变量 val,var,声明变量必须初始化:变量类型确定后不可更改 数据类型:与java有相同的数据类型,在scala中数据类型都是对象 特殊类型:Unit:表示无值,只有一个实例值写出(),相 ...

随机推荐

  1. MVC Razor 语法(转)

    http://blog.csdn.net/pasic/article/details/7072340 原文地址:MVC Razor 语法(转)作者:panzhaowen_jacki 语法名称 Razo ...

  2. android学习之activity

    Activity 的生命周期 和 J2ME 的 MIDlet 一样,在 android 中,Activity 的生命周期交给系统统一管理.与 MIDlet 不同的是安装在 android 中的所有的 ...

  3. Linux PHP实现仿百度文库预览功能

    1.安装openoffice: tar zxvf OOo_3.3.0_Linux_x86-64_install-rpm-wJRE_zh-CN.tar.gzcd RPEMrpm -ivh *.rpm安装 ...

  4. BNUOJ-29365 Join in tasks 简单数学

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29365 首先排序,然后维护一个后缀,等差求下和就可以了.. //STATUS:C++_AC ...

  5. Java 多线程同步的五种方法

    一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...

  6. 自定义文件上传的按钮的样式css+js

    核心就是一段css遮住了原生的input框,然后用js将文件的值传入到另一个指定的input框中 原文链接 http://geniuscarrier.com/how-to-style-a-html-f ...

  7. NSTimer、 NSTask、 NSThread 和 NSRunloop 之间的区别

    NSTimer是一个计时器对象,方法调用在对未来的选择对象. NSThread是一个线程类. 也就是创建一个线程. NSTask类是一个过程,一种方式运行程序从您的其他程序. NSOperation是 ...

  8. 手把手教你入门mac idea

    一.前沿 去年入职后, 公司有很多人使用的是idea , 而不是eclipse. 之前就想转向idea, 但一直没转过来~~原因是团队的人提倡用开源eclipse.现在下定决心转向idea. 虽然, ...

  9. Android studio中出现非法字符时的部分解决方法

    我将原来在Eclipse中开发的工程搬到了Android studio上来,在运行,编译程序的过程中出现了错误.提示存在非法字符. 后来发现是由于程序代码中有中文字符的出现,问题就出在对中文支持的UT ...

  10. HBase 和 MongoDB在设计上的区别

    转载:http://leongfans.iteye.com/blog/1019383 昨天搜一下mongodb的资料,介绍应用的比较多,原理介绍的不多. 粗略得看了一下,总体来说两者的设计思路差不多, ...