Scala——模式匹配;Option类(可选类)的使用;样例类的定义与使用;隐式函数实现对象转换

本文深入探讨了Scala中的模式匹配技术,展示了如何利用模式匹配简化数据处理流程,并详细解析了Option类的使用,包括Some和None的场景应用,为开发者提供了实用的代码示例。

模式匹配

模式匹配的功能非常强大,使用恰当的话可以省略很多不必要的操作

/**
  * 模式匹配使用
  */
object PatternDemo {
  def main(args: Array[String]): Unit = {
    judgeGrade("F","zs")

   val list: List[(String, (String, Int))] =  List(("A",("a",1)),("B",("B",2)),("C",("c",3)))

    //获取List中int类型数据
    list.map(tuple => tuple._2._2)

    //使用模式匹配
    val xx: List[Int] = list.map{
      case (ip,(name,age)) =>age
    }

    val list2: List[Array[Any]] = List(Array("sz", 24, 34.98), Array("ls", 23, 90.09), Array("ww", 34, 12.89))

    list2.map{
      case Array(name,orderId,money) => money
    }

    val logInfo  = "zhangsan,34,male,177777"
    val Array(name,age,sex,telphone)  = logInfo.split(",")
    println(s"$name")

  }

  /**
    * 根据 学生的成绩(类别A,B,C,D)等级,给出不同的评语
    */
  def judgeGrade(grade:String):Unit ={
    grade match {
      case "A" =>println("excellent.......")
      case "B" =>println("good......")
      case "C" =>println("just so so ......")
      case _ =>println("you need to work hader")
    }
  }
  def judgeGrade(grade:String,name:String):Unit ={
    grade match {
      case "A" =>println("excellent.......")
      case "B" =>println("good......")
      case "C" =>println("just so so ......")
      case _grade if "zs".equals(name) =>println(s"just so so ${_grade}")
      case _ =>println("you need to work hader")
    }
  }
}

Option类(可选类)的使用

/**
  * Option有2个子类
  *  -some
  *   表示有值
  *  -none
  *  表示无值
  */
object OptionDemo {
  def main(args: Array[String]): Unit = {
    val map = Map("A"->1,"B"->2)

    val opt: Option[Int] = map.get("A")
    //val optValue = if(opt.isDefined){ opt.get}
    val optValue = if(opt.isDefined) opt.get

    val x: Int = map.get("A") match {
      case Some(value) =>value
      case None => 0
    }

    /**
      * def getOrElse[B1 >: B](key: A, default: => B1): B1 = get(key) match {
      * case Some(v) => v
      * case None => default
      * }
      */
    val xx = map.getOrElse("A",0)
  }
}

样例类的定义与使用

/**
  * 定义 样例类
  *
  */
case class AAA(name:String,age:Int)

//相当于下面这段代码
class AA(name:String,age:Int)
object AA{
  def apply(name: String, age: Int): AA = new AA(name, age)
}

class People
case class Student(name:String,classRoom:String) extends People
case class Teacher(name:String,subject:String) extends People

object caseClassDemo {

  def main(args: Array[String]): Unit = {
    val  aaa = AAA("zs",18)

    check(Teacher("xx","java"))
  }

  def check(people: People): Unit ={
    people match {
      case Teacher(name,subject)=>println("teacher")
      case Student(name,classRoom)=>println("Student")
      case _ =>println("==================")
    }
  }
}

隐式函数实现对象转换

/**
  * 隐式函数
  * 可以让一个对象偷偷的变身
  * 变身函数:
  *     (0)变身函数被implicit修饰,函数名任意
  *     (1)变身函数一般在:伴生对象中
  */


//普通人
class Man(val name: String)
//object Man{
//  implicit def man2SuperMan(man:Man):SuperMan={
//    new SuperMan(man.name)
//  }
//}

object AAA{
  implicit def man2SuperMan(man:Man):SuperMan={
    new SuperMan(man.name)
  }
}

//超人:奥特曼
class SuperMan(val name: String){
  //发射激光
  def emitLaser():Unit= println("emit a laser.........")
}

object ImplicitDemo {
  def main(args: Array[String]): Unit = {
    val man = new Man("super")

    /**
      * 默认情况下:
      *   找变身函数 当前可见的作用域里面找,
      *         原类型伴生对象中找 (推荐用法)
      *         当前类下面找
      *         手动导入
      */
    import com.huadian.bigdata.oop.demo08.AAA._
    man.emitLaser()
  }
//  implicit def man2SuperMan(man:Man):SuperMan={
//    new SuperMan(man.name)
//  }
}
<think>嗯,用户想了解Scala中伴生和伴生对象的设计原因。首先,我需要回忆之前学过的Scala相关知识。记得Scala去掉了static关键字,这是因为它强调纯面向对象,而static在Java中是级别的,不属于对象,这可能不符合Scala的设计哲学。伴生和伴生对象应该就是用来替代static的。 然后,用户提供的引用里提到,伴生对象可以模拟static效果,比如通过名.方法名访问。伴生和伴生对象必须同名,并且在同一个文件中。这它们可以互相访问私有成员,这应该有助于封装和实现某些模,比如工厂方法。 另外,引用3中的子展示了伴生如何配合伴生对象实现。构造函数是私有的,只能通过伴生对象获取实。这说明伴生对象可以控制伴生的实化过程,这也是设计上的一个用途。 还有引用4提到case class和伴生对象的关系,case class会自动生成伴生对象,用于模式匹配等。这可能也是设计伴生对象的一个原因,提供方便的工厂方法和模式匹配支持。 用户的问题是关于设计目的和用途,我需要整理这些点:替代static、实现、访问私有成员、工厂方法、模式匹配支持等。可能还需要解释为什么Scala要这么做,比如保持纯OO,增强封装性,提供更灵活的实控制。 还要注意用户可能混淆了“伴生”和“半生”,引用里有时写错,但正确术语是“伴生”。需要指出正确的术语,但回答时用正确的名称。 总结下来,设计原因主要是为了去除static,保持纯面向对象;用途包括静态成员管理、单实现、工厂方法、访问控制等。需要分点说明,并举说明应用场景,比如伴生对象中的apply方法用于创建实,或者单实现。</think>Scala中伴生(Companion Class)和伴生对象(Companion Object)的设计源于其"纯面向对象"的语言哲学。以下是其核心设计目的及用途的详细解析: ### 一、设计原因 1. **消除static关键字** Java的`static`成员属于而非对象,违背了Scala"一切皆对象"的原则。伴生对象通过单模拟静态成员,如: ```scala object MathUtils { def square(x: Int): Int = x * x // 似Java的静态方法 } ``` 2. **实现对象的对称性** 伴生处理实相关逻辑,伴生对象处理级别逻辑,两者共享私有成员。如: ```scala class Database private (url: String) { private def connect(): Unit = println(s"连接$url") } object Database { def create(url: String): Database = { val db = new Database(url) db.connect() // 可访问私有方法 db } } ``` ### 二、核心用途 1. **工厂模实现** 伴生对象的`apply`方法提供优雅的对象构造方: ```scala class Vector(x: Double, y: Double) object Vector { def apply(x: Double, y: Double) = new Vector(x, y) } val v = Vector(1.0, 2.0) // 自动调用apply ``` 2. **支持** 结合参数实现多态: ```scala trait JsonWriter[A] { def write(value: A): String } object JsonWriter { implicit val intWriter: JsonWriter[Int] = (value: Int) => s"$value" } ``` 3. **模式匹配增强** case自动生成伴生对象支持模解构: ```scala case class Person(name: String, age: Int) Person("Alice", 30) match { case Person(n, a) => println(s"$n, $a岁") } ``` ### 三、典型应用场景 1. **资源配置管理** ```scala class Config private (val path: String) object Config { private lazy val instance = new Config("default.conf") def load(): Config = instance } ``` 2. **领域特定语言(DSL)** ```scala object SqlDSL { def SELECT(columns: String*) = new QueryBuilder(columns) } class QueryBuilder(columns: Seq[String]) { def FROM(table: String): String = s"SELECT ${columns.mkString(",")} FROM $table" } ``` 3. **线程安全缓存** ```scala object Cache { private val store = new ConcurrentHashMap[String, Any] def get(key: String): Option[Any] = Option(store.get(key)) def put(key: String, value: Any): Unit = store.put(key, value) } ``` [^1]: 这种设计使Scala保持面向对象纯粹性的同时,提供了比Java更灵活的级别操作能力。伴生对象本质上是通过编译生成的单实现的,如`ClassName$`[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无名一小卒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值