第八章 scala语言--match、PartialFunction、implicit

第八章 scala语言–match、PartialFunction、implicit



前言

今天是学习Scala第八天打卡,开始学习match、PartialFunction、implicit。


一、match(模式匹配)

Scala 提供了强大的模式匹配机制,应用也非常广泛。
一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
(1) 简单的整型值模式匹配

object Test {
   def main(args: Array[String]) {
      println(matchTest(3))

   }
   def matchTest(x: Int): String = x match {
      case 1 => "one"
      case 2 => "two"
      case _ => "many"
   }
}
执行结果:
---------------------------------------------------------------------------------------------------------------------------
many
  • match 对应 Java 里的 switch,但是写在选择器表达式之后。即: 选择器 match {备选项}。
  • match 表达式通过以代码编写的先后次序尝试每个模式来完成计算,只要发现有一个匹配的case,剩下的case不会继续匹配。

(2) 不同数据类型的模式匹配

object Test {
  def main(args: Array[String]) {
    println(matchTest("two"))
    println(matchTest("test"))
    println(matchTest(1))
    println(matchTest(6))

  }
  def matchTest(x: Any): Any = x match {
    case 1 => "one"
    case "two" => 2
    case y: Int => "scala.Int"
    case _ => "many"
  }
}
执行结果:
---------------------------------------------------------------------------------------------------------------------------
2
many
one
scala.Int

(3) 使用Iterator遍历并模式匹配

  object Lesson06_match {
  def main(args: Array[String]): Unit = {
    val tup: (Double, Int, String, Boolean, Int) = (1.0,88,"abc",false,44)
    val iter: Iterator[Any] = tup.productIterator
    val res: Iterator[Unit] = iter.map(
      (x) => {
        x match {
          case 1 => println(s"$x...is 1")
          case 88 => println(s"$x ...is 88")
          case false => println(s"$x...is false")
          case w: Int if w > 50 => println(s"$w...is  > 50")
          case _ => println("wo ye bu zhi dao sha lei xing ")
        }
      }
    )
    while(res.hasNext)  println(res.next())
  }
}
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
1.0...is 1
()
88 ...is 88
()
wo ye bu zhi dao sha lei xing 
()
false...is false
()
wo ye bu zhi dao sha lei xing 
()

(4) 使用样例类

使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类,经过优化以用于模式匹配。

  object Test {
   def main(args: Array[String]) {
        val alice = new Person("Alice", 25)
        val bob = new Person("Bob", 32)
        val charlie = new Person("Charlie", 32)
   
    for (person <- List(alice, bob, charlie)) {
        person match {
            case Person("Alice", 25) => println("Hi Alice!")
            case Person("Bob", 32) => println("Hi Bob!")
            case Person(name, age) =>
               println("Age: " + age + " year, name: " + name + "?")
         }
      }
   }
   // 样例类
   case class Person(name: String, age: Int)
}
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
Hi Alice!
Hi Bob!
Age: 32 year, name: Charlie?

在声明样例类时,下面的过程自动发生了:

  • 构造器的每个参数都成为val,除非显式被声明为var,但是并不推荐这么做;
  • 在伴生对象中提供了apply方法,所以可以不使用new关键字就可构建对象;
  • 提供unapply方法使模式匹配可以工作;
  • 生成toString、equals、hashCode和copy方法,除非显示给出这些方法的定义。

二、PartialFunction(偏函数)

object Lesson07_PartialFunction {

  def main(args: Array[String]): Unit = {

    def xxx:PartialFunction[  Any,String] ={
      case "hello"  => "val is hello"
      case x:Int => s"$x...is int"
      case _ => "none"
    }
    println(xxx(44))
    println(xxx("hello"))
    println(xxx("hi"))
    
  } 
}
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
 44...is int
val is hello
none

更多:https://cloud.tencent.com/developer/article/1657841

三、implicit

1.JAVA中可以使用forEach()方法对List集合进行遍历,例如:

  public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.forEach(e ->{
            System.out.println(e);
        });
    }
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
 张三
李四
王五
赵六

如果用Scala呢,发现并没有forEach()函数。当然你可以自己定义一个,例如:

 val listArray = new util.ArrayList[Int]()
    listArray.add(1)
    listArray.add(2)
    listArray.add(3)
 def foreach[T](list:util.ArrayList[T], f:(T)=>Unit): Unit ={
      val iter: util.Iterator[T] = list.iterator()
      while(iter.hasNext) f(iter.next())
    }

    foreach(listArray,println)
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
1
2
3

或者,你可以这样,例如:

class XXX[T](list:util.LinkedList[T]){

  def foreach( f:(T)=>Unit): Unit ={
    val iter: util.Iterator[T] = list.iterator()
    while(iter.hasNext) f(iter.next())
  }
}

val xx = new XXX(listLinked)
xx.foreach(println)
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
 1
 2
 3

2.但这样还是不能像list.forEach()直接使用。这里看一下下面的示例:

object Lesson08_implicit {
  def main(args: Array[String]): Unit = {
      val listArray = new util.ArrayList[Int]()
      listArray.add(1)
      listArray.add(2)
      listArray.add(3)

   implicit def demo[T](list:java.util.ArrayList[T]) ={
      val iter: util.Iterator[T] = list.iterator()
      new Bex(iter)
   }
   listArray.foreach(println)
   }
}
class Bex[T](list:util.Iterator[T]){

  def foreach( f:(T)=>Unit): Unit ={

    while(list.hasNext) f(list.next())
  }
}
执行结果:
 ---------------------------------------------------------------------------------------------------------------------------
 1
 2
 3

上面的代码,发现竟然实现了,起码形式上是实现了。这里做了什么?
首先这些代码交给scala的编译器去处理。
1,scala编译器编译到 list.foreach(println) ,发现找不到foreach()
2,去寻找有没有implicit关键字定义的方法,且方法的参数正好是list的类型!!!
3,编译器把代码改写为

   val xx = new XXX(list)
      xx.foreach(println)  
   。。。

总结

以上就是今天要讲的内容,本文就scala的match、PartialFunction、implicit使用方面列举了一些示例及使用技巧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值