Scala--第八天

TheBigBlue 2020-02-13

一、option类型

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

def func(a: Double, b: Double): Option[Double] = {
    if (b != 0) {
      //没错的情况下 返回值用Some函数包起来
      Some(a / b)
    } else {
      //无值 返回None
      None
    }
  }

  def main(args: Array[String]): Unit = {
    var a = func(2.0, 2.0)
    println(a)
    //查看返回值的方法
    println(a.getOrElse(0.0))
    //Some(1.0)
    //1.0

  }

二、偏函数

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

      case 1 => "..."

      case 2 => "..."

      case _ => "其他"

      }

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

三、正则表达式

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

//正则表达式
    var r: Regex =
      """+\..+""".r
    var x = ""
    //该方法返回一个迭代器
    var res = r.findAllMatchIn(x)
    print(res.next())
    //

四、异常处理

  格式:try{代码}

     catch{

      //异常处理

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

     ...

      }

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

try {
      2 / 0
    }
    catch {
      case ex: ArithmeticException => println("除数不可以是0")
    }
    finally {
      println("无论如何最后我都会执行的")
    }
    //除数不可以是0
    //无论如何最后我都会执行的

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

五、提取器

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

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

case class Person(var name: String)


  def main(args: Array[String]): Unit = {
    var a: Any = Person("cmx")
    a match {
      case Person(name) => println(s"${name}")
    }
    //结果
    //cmx
  }

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

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

class Person(var name: String)


  object Person {
    //快速创建对象的方法
    def apply(name: String) = {
      new Person(name)
    }

    //提取器 :参数类型:与类保持一致,返回值使用Option,避免空指针
    def unapply(arg: Person): Option[String] = {
      if (arg != null) {
        Some(arg.name)
      } else {
        None
      }
    }
  }

  class User(var id: Int, var name: String)

  object User {
    def apply(id: Int, name: String) = new User(id, name)

    //完整写法
    //def unapply(arg: User): Option[(Int, String)]
    //简写 利用类型推导
    def unapply(arg: User) = {
      var res = (arg.id, arg.name)
      Some(res)
    }
  }

  def main(args: Array[String]): Unit = {
    //定义时使用Any 防止模式匹配时不知是那个类型
    var a: Any = Person("cmx")
    var b: Any = User(1, "cmx01")

    a match {
      case Person(name) => println(s"${name}")
      case User(id, name) => println(s"${id}${name}")
    }
    //cmx
    b match {
      case Person(name) => println(s"${name}")
      case User(id, name) => println(s"${id}${name}")
    }
    //1cmx01

  }

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

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

class Cmx[T](var name: T) {
    var age: T = _
  }

  def main(args: Array[String]): Unit = {
    var a = new Cmx[String]("cmx")
    println(a.name.getClass)
    //class java.lang.String
    var b = new Cmx[Int](123)
    println(b.name.getClass)
    //int

    //样例类也可以
    case class Cmx01[T](var name: T)
    var c = Cmx01[Double](10.0)
    println(c.name.getClass)
    //double
  }

2.泛型方法

def func[T](name: T) = {
    println(name)
  }

  def func2[T](a: Array[T]) = {
    a.foreach(println(_))
  }

  def main(args: Array[String]): Unit = {
    func[String]("cmx")
    func[Int](1)
    //cmx
    //1
    //赋值时[T]的类型 决定后面参数的类型 二者必须保持一致
    func2[String](Array("1", "2"))
    func2[Int](Array(1, 2, 3))
  }

  3.泛型的上下界

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

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

class Cmx

  class Cmx01 extends Cmx

  //下界
  def func[T >: Cmx01](name: T) = println(name)

  //上界
  def func1[T <: Cmx01](name: T) = println(name)

  def main(args: Array[String]): Unit = {
    //下界演示:只要时Cmx01或者其父类均可,但是依旧要保持前后的二者类型相同
    func[Cmx](new Cmx)
    func[Cmx01](new Cmx01)
    //
    //

    //上界演示
    func1[Cmx](new Cmx)
    //直接报错 ,意为最大就是Cmx01 ,因为它是上界
    //Error:(26, 10) type arguments [cmm_test.test2.Cmx] do not conform to method func1‘s type parameter bounds [T <: cmm_test.test2.Cmx01]
    func1[Cmx01](new Cmx01)
    //

七、柯里化

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

  格式案例:

def test(x:Int,y:Int):Unit = {
println(x+y)
}
//演变成单个参数的列表
def test(x:Int)(y:Int):Unit = {
println(x+y)
}

test(1)(2)
//格式:参数列表放在前面,后面的第二个参数是一个函数格式(函数名:(参数类型#与前面的类型保持一致)=>返回值类型)
  def test(x: Int)(fun1: (Int) => Int) = {
    fun1(x)
  }

  def main(args: Array[String]): Unit = {
    //借用函数编程 调用函数
    println(test(1)(_ + 11))
    //12
  }

八、隐式转换

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

//定义方法阶段:构造器的参数 类型必须时String  因为你要添加这个原始类的功能
  class Text(var s: String) {
    //这个方法就是我们要添加String类的新方法,名字即为方法
    //方法自定义:参数可写可不写 扩展性大
    def func() = {
      println(s"${s}=>cmx")
    }
  }

  //通过implicit 实装与String
  //关键字imolicit 后的方法里的参数类型也要是String,后面的实例化 必须是定义阶段的类
  implicit def func2(e: String) = new Text(e)

  def main(args: Array[String]): Unit = {
    //测试
    var a: String = "hhh"
    a.func()
    //hhh=>cmx
  }
//自定义的一个类 参数类型需是要添加方法的类
  class RichFile(val f: File) {
    def read() = {
      //scala中的io操作读取文件并转化成字符串
      Source.fromFile(f).mkString
    }
  }

  //隐式转换实装  implicit 关键字  函数名 随意 参数名随意 参数类型 :要添加方法的类
  //函数体:new 前面定义过的类然后将参数放进去
  implicit def Cmx(f: File) = new RichFile(f)

  def main(args: Array[String]): Unit = {
    //文件自定义 路径要写对  盘符不区分大小写
    //实例化File 对象  这时该对象就可以调用read的方法了
    var f = new File("e:/1.txt")
    val str = f.read()
    println(str)
    //ssss
  }

相关推荐

kekeromer / 0评论 2020-04-30