编写如下代码:

object MatchTest {
def foo(a : Any) : String =
{
a match {
case 1 => "int:1"
case x : Int if (x > 50) => "int(>50):" + x
case x : Int => "int:" + x
case (x, y) => "tuple:" + x + "," + y
case h :: t => "list:" + h + "," + t
case Array(90) => "array:90"
case Array(90, x) => "array:90," + x
case _ => ":("
}
} def main(args : Array[String]) {
println(foo(1))
println(foo(51))
println(foo(49))
println(foo((1, 2)))
println(foo((1, 2, 3)))
println(foo((3 -> 4)))
println(foo(List(80, 81)))
println(foo(Array(90, 91)))
}
}

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

  public String foo(Object a)
{
int i = 0; int j = 0; Object localObject1 = a;
String str;
if (BoxesRunTime.equals(BoxesRunTime.boxToInteger(1), localObject1)) { str = "int:1"; } else {
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;
}
}
if (i != 0)
{
str = new StringBuilder().append("int:").append(BoxesRunTime.boxToInteger(j)).toString();
} 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();
} 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 {
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; } } }
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; } } }
str = ":(";
}
}
label464: return str;
}

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

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

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

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

反编译代码:

  public void main(String[] args) {
String str = "bluejoe2008@gmail.com";
String str1 = str;
Option localOption = unapply(str1);
BoxedUnit localBoxedUnit;
if (localOption.isEmpty()) {
Predef..MODULE$.println("this is not an email address "); localBoxedUnit = BoxedUnit.UNIT;
}
else
{
String username = (String)((Tuple2)localOption
.get())._1(); String host = (String)((Tuple2)localOption
.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;
}
}

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

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

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

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

val namesString = "xiao ming,xiao hong,tom"
namesString match {
case Names(first, second, third) => {
println("the string contains three people's names")
println(s"$first $second $third")
}
case _ => println("nothing matched")
}

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

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

最新文章

  1. Python的第三天
  2. php回调函数
  3. visualSVN server库迁移
  4. SQL语句新建表,同时添加主键、索引、约束
  5. Vim的tagbar插件
  6. win8如何删除未知账户(s-1-5-21-2000478354-1390067357-725345543-1003)
  7. Asterisk 安装与配置
  8. java 线程池的用法
  9. 使得fiddler来抓包查看微信浏览器的网页源码
  10. hdu_4467_Graph(莫队算法思想)
  11. sql语句:if exists语句使用
  12. 关于C++中计时的方法
  13. Foxmail 7.0破解版,拷贝到新机器后,发送邮件乱码问题
  14. 怎么用DreamWare新建立一个静态网站的站点
  15. 给WEB初学者的一些有效率的建议
  16. 菜鸟教程之学习Shell script笔记(上)
  17. 不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny"),或者 是通过包含 overrideMode="Deny" 或旧有的 allowOverride="false" 的位置标记明确设置的。
  18. RestTemplate proxy 设置方式
  19. NeoFinder for Mac(增强型文件管理工具)破解版安装
  20. Android ——多线程处理之多线程用法大集合(转)

热门文章

  1. mvc5 HTML Helper
  2. [OC Foundation框架 - 1] 常用结构体
  3. SHH入门:Spring框架简介
  4. sizeof _countof _tcslen的比较
  5. angular-tour 用户新手引导
  6. UINavgation日常小bug-有兴趣的朋友可以看看
  7. SVG 矢量图形格式
  8. SQL连接查询的方式
  9. IOS 横屏中添加UIImagePickerController获取系统图片
  10. 用Bootstrap 写了个站点