博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
scala学习笔记:match与unapply()
阅读量:5252 次
发布时间:2019-06-14

本文共 4813 字,大约阅读时间需要 16 分钟。

编写如下代码:

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;    }  }

如下内容摘录于:

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

转载于:https://www.cnblogs.com/bluejoe/p/5115867.html

你可能感兴趣的文章
ProxySQL Scheduler
查看>>
源代码的下载和编译读后感
查看>>
Kafka学习笔记
查看>>
Octotree Chrome安装与使用方法
查看>>
用CALayer实现下载进度条控件
查看>>
Windows 环境下基于 Redis 的 Celery 任务调度模块的实现
查看>>
趣谈Java变量的可见性问题
查看>>
C# 强制关闭当前程序进程(完全Kill掉不留痕迹)
查看>>
ssm框架之将数据库的数据导入导出为excel文件
查看>>
语音识别中的MFCC的提取原理和MATLAB实现
查看>>
java string
查看>>
验证组件FluentValidation的使用示例
查看>>
0320-学习进度条
查看>>
JAVA跨域CORS
查看>>
正确的在循环list的时候删除list里面的元素
查看>>
ERP渠道文档详细和修改(二十五)
查看>>
C#正则Groups高级使用方法
查看>>
ecshop安装常见问题及解决办法
查看>>
解决windows系统的oracle数据库不能启动ora-00119和ora-00130的问题
查看>>
ip相关问题解答
查看>>