Scala---样例类+隐式转换

样例类(case classes)

1、概念理解

使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val),当构造参数是声明为var类型的,它将帮你实现setter和getter方法。

  • 样例类默认帮你实现了toString,equals,copy和hashCode等方法。
  • 样例类可以new, 也可以不用new

2、例子:结合模式匹配的代码

复制代码
1.case class Person1(name:String,age:Int)
2.
3.object Lesson_CaseClass {
4.  def main(args: Array[String]): Unit = {
5.    val p1 = new Person1("zhangsan",10)
6.    val p2 = Person1("lisi",20)
7.    val p3 = Person1("wangwu",30)
8.
9.    val list = List(p1,p2,p3)
10.    list.foreach { x => {
11.       x match {
12.          case Person1("zhangsan",10) => println("zhangsan")
13.          case Person1("lisi",20) => println("lisi")
14.          case _ => println("no match")
15.       }
16.    } }
17.
18.  }
19.}

隐式转换

隐式转换是在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。

1、隐式值与隐式参数

隐式值是指在定义参数时前面加上implicit。隐式参数是指在定义方法时,方法中的部分参数是由implicit修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式转换作用就是:当调用方法时,不必手动传入方法中的隐式参数,Scala会自动在作用域范围内寻找隐式值自动传入。

隐式值和隐式参数注意:

1). 同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。

2). implicit 关键字必须放在隐式参数定义的开头

3). 一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,调用时直接创建类型不传入参数即可。

4). 一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次

复制代码
1.object Lesson_ImplicitValue {
2.
3.  def Student(age:Int)(implicit name:String,i:Int)= {
4.    println( s"student :$name ,age = $age ,score = $i")
5.  }
6.  def Teacher(implicit name:String) ={
7.    println(s"teacher name is = $name")
8.  }
9.
10.  def main(args: Array[String]): Unit = {
11.    implicit val zs = "zhangsan"
12.    implicit val sr = 100
13.
14.    Student(18)
15.    Teacher
16.  }
17.}

2、隐式转换函数

隐式转换函数是使用关键字implicit修饰的方法。当Scala运行时,假设如果A类型变量调用了method()这个方法,发现A类型的变量没有method()方法,而B类型有此method()方法,会在作用域中寻找有没有隐式转换函数将A类型转换成B类型,如果有隐式转换函数,那么A类型就可以调用method()这个方法。

隐式转换函数注意:隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关,所以作用域内不能有相同的参数类型和返回类型的不同名称隐式转换函数。

复制代码
1.class Animal(name:String){
2.  def canFly(): Unit ={
3.    println(s"$name can fly...")
4.  }
5.}
6.class Rabbit(xname:String){
7.  val name = xname
8.}
9.object Lesson_ImplicitFunction {
10.
11.  implicit def rabbitToAnimal(rabbit:Rabbit):Animal = {
12.     new Animal(rabbit.name)
13.  }
14.
15.  def main(args: Array[String]): Unit = {
16.    val rabbit = new Rabbit("RABBIT")
17.    rabbit.canFly()
18.  }
19.}

3、隐式类

使用implicit关键字修饰的类就是隐式类。若一个变量A没有某些方法或者某些变量时,而这个变量A可以调用某些方法或者某些变量时,可以定义一个隐式类,隐式类中定义这些方法或者变量,隐式类中传入A即可。

隐式类注意:

1).隐式类必须定义在类,包对象,伴生对象中。

2).隐式类的构造必须只有一个参数,同一个类,包对象,伴生对象中不能出现同类型构造的隐式类。

复制代码
1.class Rabbit(s:String){
2.  val name = s
3.}
4.
5.object Lesson_ImplicitClass {
6.
7.  implicit class Animal(rabbit:Rabbit){
8.    val tp = "Animal"
9.    def canFly() ={
10.      println(rabbit.name +" can fly...")
11.    }
12.  }
13.
14.  def main(args: Array[String]): Unit = {
15.    val rabbit = new Rabbit("rabbit")
16.    rabbit.canFly()
17.    println(rabbit.tp)
18.  }
19.}
相关推荐
Dovis(誓平步青云)1 小时前
《Linux CPU频率为何忽高忽低:cpufreq、idle状态与性能抖动教程》
linux·运维·服务器·spring boot·后端·生成对抗网络
To_OC8 小时前
手写 AI 编程 Agent 的命令执行工具:我被 child_process 坑出来的实战经验
后端·node.js·agent
科技道人8 小时前
记录 默认置灰/禁用 app ‘Search Engine Selector‘ 的disable按钮
开发语言·前端·javascript
逝水无殇11 小时前
C# 异常处理详解
开发语言·后端·c#
玖玥拾12 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾12 小时前
Rust 学习目录
开发语言·学习·rust
考虑考虑13 小时前
Sentinel安装
java·后端·微服务
IT_陈寒13 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端
云泽80813 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
碎碎念_49213 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端