• Scala--第八天


    一、option类型

      定义:通过该类型可以有效的避免空指针异常

     1   def func(a: Double, b: Double): Option[Double] = {
     2     if (b != 0) {
     3       //没错的情况下 返回值用Some函数包起来
     4       Some(a / b)
     5     } else {
     6       //无值 返回None
     7       None
     8     }
     9   }
    10 
    11   def main(args: Array[String]): Unit = {
    12     var a = func(2.0, 2.0)
    13     println(a)
    14     //查看返回值的方法
    15     println(a.getOrElse(0.0))
    16     //Some(1.0)
    17     //1.0
    18 
    19   }

    二、偏函数

      格式:val 函数名:PartialFunction[参数类型,返回值类型]={

          case 1 => "..."

          case 2 => "..."

          case _ => "其他"

          }

     1     val cmm: PartialFunction[Int, String] = {
     2       case 1 => "1"
     3       case 2 => "2"
     4       case _ => "其他"
     5     }
     6     println(cmm(1))
     7     println(cmm(2))
     8     println(cmm(3))
     9     //1
    10     //2
    11     //其他
     1     //把偏函数作为其他方法的参数传入,类比函数化编程
     2     var li = 1.to(10).toList
     3     //需求:将列表的每一个元素转换成属于他的范围
     4     var m = li.map {
     5       case m if m >= 1 && m <= 3 => "[1-3]"
     6       case m if m >= 4 && m <= 7 => "[4-7]"
     7       case m if m > 7 => "[7-*]"
     8     }
     9     println(m)
    10     //List([1-3], [1-3], [1-3], [4-7], [4-7], [4-7], [4-7], [7-*], [7-*], [7-*])

    三、正则表达式

      格式:var 变量名:Regex =""" 规则""".r

    1     //正则表达式
    2     var r: Regex =
    3       """.+@.+..+""".r
    4     var x = "1234@qq.com"
    5     //该方法返回一个迭代器
    6     var res = r.findAllMatchIn(x)
    7     print(res.next())
    8     //1234@qq.com

    四、异常处理

      格式:try{代码}

         catch{

          //异常处理

         case ex:Exception【错误类型】 => "返回值"

         ...

          }

         finally{最后都会执行的代码}

     1     try {
     2       2 / 0
     3     }
     4     catch {
     5       case ex: ArithmeticException => println("除数不可以是0")
     6     }
     7     finally {
     8       println("无论如何最后我都会执行的")
     9     }
    10     //除数不可以是0
    11     //无论如何最后我都会执行的

       主动抛出异常:throw new Exception("这是我自己主动抛出的异常")

    五、提取器

      定义:把对象相关属性,通过${} 提取,样例类实现了提取器,而普通的类没有提取器之说

      本质:就是把一个对象的属性 获取出来 通过元祖的形式返回

     1   case class Person(var name: String)
     2 
     3 
     4   def main(args: Array[String]): Unit = {
     5     var a: Any = Person("cmx")
     6     a match {
     7       case Person(name) => println(s"${name}")
     8     }
     9     //结果
    10     //cmx
    11   }

      自定义提取器:提取器只能定义在伴生对象中,且于apply方法成对出现

      注意:提取器的 返回值是多个的话用元组括起来,只有一个的话直接返回即可

     1   class Person(var name: String)
     2 
     3 
     4   object Person {
     5     //快速创建对象的方法
     6     def apply(name: String) = {
     7       new Person(name)
     8     }
     9 
    10     //提取器 :参数类型:与类保持一致,返回值使用Option,避免空指针
    11     def unapply(arg: Person): Option[String] = {
    12       if (arg != null) {
    13         Some(arg.name)
    14       } else {
    15         None
    16       }
    17     }
    18   }
    19 
    20   class User(var id: Int, var name: String)
    21 
    22   object User {
    23     def apply(id: Int, name: String) = new User(id, name)
    24 
    25     //完整写法
    26     //def unapply(arg: User): Option[(Int, String)]
    27     //简写 利用类型推导
    28     def unapply(arg: User) = {
    29       var res = (arg.id, arg.name)
    30       Some(res)
    31     }
    32   }
    33 
    34   def main(args: Array[String]): Unit = {
    35     //定义时使用Any 防止模式匹配时不知是那个类型
    36     var a: Any = Person("cmx")
    37     var b: Any = User(1, "cmx01")
    38 
    39     a match {
    40       case Person(name) => println(s"${name}")
    41       case User(id, name) => println(s"${id}${name}")
    42     }
    43     //cmx
    44     b match {
    45       case Person(name) => println(s"${name}")
    46       case User(id, name) => println(s"${id}${name}")
    47     }
    48     //1cmx01
    49 
    50   }

    六、泛型 Array[Int] --> 具体类型

      1.泛型类:可以根据需要,随意改变属性的类型

     1   class Cmx[T](var name: T) {
     2     var age: T = _
     3   }
     4 
     5   def main(args: Array[String]): Unit = {
     6     var a = new Cmx[String]("cmx")
     7     println(a.name.getClass)
     8     //class java.lang.String
     9     var b = new Cmx[Int](123)
    10     println(b.name.getClass)
    11     //int
    12 
    13     //样例类也可以
    14     case class Cmx01[T](var name: T)
    15     var c = Cmx01[Double](10.0)
    16     println(c.name.getClass)
    17     //double
    18   }

      2.泛型方法

     1   def func[T](name: T) = {
     2     println(name)
     3   }
     4 
     5   def func2[T](a: Array[T]) = {
     6     a.foreach(println(_))
     7   }
     8 
     9   def main(args: Array[String]): Unit = {
    10     func[String]("cmx")
    11     func[Int](1)
    12     //cmx
    13     //1
    14     //赋值时[T]的类型 决定后面参数的类型 二者必须保持一致
    15     func2[String](Array("1", "2"))
    16     func2[Int](Array(1, 2, 3))
    17   }

      3.泛型的上下界

      上界:[T <: 类型]  或者是这个类型 或者 是这个类型的子类

      下界:[T >: 类型] 或者是这个类型 或者 是这个类型父亲

     1   class Cmx
     2 
     3   class Cmx01 extends Cmx
     4 
     5   //下界
     6   def func[T >: Cmx01](name: T) = println(name)
     7 
     8   //上界
     9   def func1[T <: Cmx01](name: T) = println(name)
    10 
    11   def main(args: Array[String]): Unit = {
    12     //下界演示:只要时Cmx01或者其父类均可,但是依旧要保持前后的二者类型相同
    13     func[Cmx](new Cmx)
    14     func[Cmx01](new Cmx01)
    15     //cmm_test.test2$Cmx@23223dd8
    16     //cmm_test.test2$Cmx01@4ec6a292
    17 
    18     //上界演示
    19     func1[Cmx](new Cmx)
    20     //直接报错 ,意为最大就是Cmx01 ,因为它是上界
    21     //Error:(26, 10) type arguments [cmm_test.test2.Cmx] do not conform to method func1's type parameter bounds [T <: cmm_test.test2.Cmx01]
    22     func1[Cmx01](new Cmx01)
    23     //cmm_test.test2$Cmx01@1b40d5f0

    七、柯里化

      定义:柯里化(Currying) 将原来接受多个参数的方法转换为多个只接受一个参数的方法列表

      格式案例:

    1 def test(x:Int,y:Int):Unit = {
    2 println(x+y)
    3 }
    4 //演变成单个参数的列表
    5 def test(x:Int)(y:Int):Unit = {
    6 println(x+y)
    7 }
    8 
    9 test(1)(2)
     1   //格式:参数列表放在前面,后面的第二个参数是一个函数格式(函数名:(参数类型#与前面的类型保持一致)=>返回值类型)
     2   def test(x: Int)(fun1: (Int) => Int) = {
     3     fun1(x)
     4   }
     5 
     6   def main(args: Array[String]): Unit = {
     7     //借用函数编程 调用函数
     8     println(test(1)(_ + 11))
     9     //12
    10   }

    八、隐式转换

      定义:为原本定义好的类,增加新的功能

     1   //定义方法阶段:构造器的参数 类型必须时String  因为你要添加这个原始类的功能
     2   class Text(var s: String) {
     3     //这个方法就是我们要添加String类的新方法,名字即为方法
     4     //方法自定义:参数可写可不写 扩展性大
     5     def func() = {
     6       println(s"${s}=>cmx")
     7     }
     8   }
     9 
    10   //通过implicit 实装与String
    11   //关键字imolicit 后的方法里的参数类型也要是String,后面的实例化 必须是定义阶段的类
    12   implicit def func2(e: String) = new Text(e)
    13 
    14   def main(args: Array[String]): Unit = {
    15     //测试
    16     var a: String = "hhh"
    17     a.func()
    18     //hhh=>cmx
    19   }
     1   //自定义的一个类 参数类型需是要添加方法的类
     2   class RichFile(val f: File) {
     3     def read() = {
     4       //scala中的io操作读取文件并转化成字符串
     5       Source.fromFile(f).mkString
     6     }
     7   }
     8 
     9   //隐式转换实装  implicit 关键字  函数名 随意 参数名随意 参数类型 :要添加方法的类
    10   //函数体:new 前面定义过的类然后将参数放进去
    11   implicit def Cmx(f: File) = new RichFile(f)
    12 
    13   def main(args: Array[String]): Unit = {
    14     //文件自定义 路径要写对  盘符不区分大小写
    15     //实例化File 对象  这时该对象就可以调用read的方法了
    16     var f = new File("e:/1.txt")
    17     val str = f.read()
    18     println(str)
    19     //ssss
    20   }

      

  • 相关阅读:
    牛客练习赛64 D.宝石装箱 【容斥原理+背包DP】
    洛谷 P5212 SubString【SAM+LCT】
    洛谷 P4219 [BJOI2014]大融合【LCT】
    洛谷 P1501 [国家集训队]Tree II【LCT】
    洛谷 P5357 【模板】AC自动机(二次加强版)
    洛谷 P3690 【模板】Link Cut Tree (动态树)
    洛谷 P2463 [SDOI2008]Sandy的卡片【后缀数组】
    P3181 [HAOI2016]找相同字符【后缀数组】
    洛谷 SP705 【后缀数组】
    牛客小白月赛18 E.Forsaken的数列【Splay】
  • 原文地址:https://www.cnblogs.com/cmxbky1314/p/12303310.html
Copyright © 2020-2023  润新知