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   }

 

 

  

posted @ 2020-02-13 17:55  紫菱_cmx  阅读(135)  评论(0编辑  收藏  举报