Scala中的类型检查和转换,以及泛型,scala泛型的协变和逆变

Scala中的类型检查和转换,以及泛型

类型检查和转换

  1. 说明
    (1) obj.isInstanceOf[T]:判断 obj 是不是T 类型。
    (2) obj.asInstanceOf[T]:将 obj 强转成 T 类型。
    (3) classOf 获取对象的类名。
  2. 案例
class Person{}object Person {
def main(args: Array[String]): Unit = {val person = new Person//(1)判断对象是否为某个类型的实例
val boolPerson: Boolean = person.isInstanceOf[Person]if ( boolPerson) {
//(2)将对象转换为某个类型的实例
val p1: Person = person.asInstanceOf[Person]
println(p1)
}//(3)获取类的信息
val pClass: Class[Person] = classOf[Person]
println(pClass)
}
}

枚举类与应用类

1.说明
(1)枚举类:需要继承 Enumeration
(2)应用类:需要继承App
2. 案例

object Test {
def main(args: Array[String]): Unit = {println(Color.RED)
}
}
// 枚举类
object Color extends Enumeration {
val RED = Value(1, "red")
val YELLOW = Value(2, "yellow")
val BLUE = Value(3, "blue")
}
// 应用类
object Test20 extends App {
println("xxxxxxxxxxx");
}

Type 定义新类型

1.说明
使用 type 关键字可以定义新的数据数据类型名称,本质上就是类型的一个别名.
2. 案例

object Test {
def main(args: Array[String]): Unit = {
//定义一个类型S
type S=String
var v:S="abc"
def test():S="xyz"
}
}

Scala的泛型

Scala 中的泛型可以通过类型参数来实现,用于增加代码的灵活性和重用性。在 Scala 中,泛型可以应用于类、特质和方法等不同的上下文。

下面是一些示例来说明 Scala 中如何使用泛型:

1. 类的泛型参数:

class Box[T](content: T) {def getContent: T = content
}val intBox = new Box[Int](42)
val stringBox = new Box[String]("Hello")val intValue: Int = intBox.getContent
val stringValue: String = stringBox.getContent

在上述示例中,Box 类使用一个类型参数 T,它可以接受不同类型的内容。在创建 intBoxstringBox 实例时,我们分别指定了 T 的具体类型为 IntString。通过 getContent 方法,我们可以获得相应的内容,并将其转换为对应的类型。

2. 方法的泛型参数:

def printContent[T](content: T): Unit = {println(content)
}printContent(42)        // 输出:42
printContent("Hello")   // 输出:Hello

在上述示例中,printContent 方法也使用了一个类型参数 T。该方法可以接受任意类型的参数,并将其打印出来。

Scala 还支持上界(upper bounds)和视图界定(view bounds)等高级的泛型概念,用于对类型参数进行约束或扩展。例如,可以使用上界来限制类型参数必须是某个类型的子类,使用视图界定则可以通过隐式转换来实现对类型参数的扩展。

总之,Scala 中的泛型能够极大地提升代码的灵活性和重用性,使得我们可以编写更加通用和类型安全的代码。

3.泛型例子

import scala.reflect.ClassTag//定义带泛型的类
class Triple[F, S, T](val first: F, val second: S, val third: T)object Test extends App{val triple = new Triple("Spark", 3, 3.14)val bigData = new Triple[String, String, Char]("spark", "hadoop", 'd')//定义带泛型的函数def getData[T](list: List[T]) = list(list.length / 2)println(getData(List("spark", "hadoop", "r")))//讲泛型函数传递给一个函数, 必须指定类型和_val f = getData[Int] _println(f(List(1, 2, 3, 4)))def biuldArray[T: ClassTag](len: Int) = new Array[T](len)println(biuldArray[Int](5).toList)//f的输入参数是A类型,产出是List[A], b必须是A类型def foo[A, B](f: A => List[A], b: A) = f(b)
}

泛型的协变和逆变

  1. 语法

class MyList[+T]{ //协变
}class MyList[-T]{ //逆变
}class MyList[T] //不变
  1. 说明
  • 协变:
    Son 是 Father 的子类,则 MyList[Son] 也作为 MyList[Father]的“子类”。
  • 逆变:
    Son 是 Father 的子类,则 MyList[Son]作为 MyList[Father]的“父类”。
  • 不变:
    Son 是 Father 的子类,则 MyList[Father]与 MyList[Son]“无父子关系”。
  1. 案例
//泛型模板
//class MyList<T>{}
//不变
//class MyList[T]{}
//协变
//class MyList[+T]{}
//逆变
//class MyList[-T]{}class Parent{}
class Child extends Parent{}
class SubChild extends Child{}object Scala_TestGeneric {
def main(args: Array[String]): Unit = {
//var s:MyList[Child] = new MyList[SubChild]
}
}

Scala泛型上下限

  1. 语法
Class PersonList[T <: Person]{ //泛型上限
}
Class PersonList[T >: Person]{ //泛型下限
}
  1. 说明
    泛型的上下限的作用是对传入的泛型进行限定。
  2. 案例
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}object Scala_TestGeneric {
def main(args: Array[String]): Unit = {//test(classOf[SubChild])
//test[Child](new SubChild)
}
//泛型通配符之上限
//def test[A <: Child](a:Class[A]): Unit ={
// println(a)
//}//泛型通配符之下限
//def test[A >: Child](a:Class[A]): Unit ={
// println(a)
//}//泛型通配符之下限 形式扩展
def test[A >: Child](a:A): Unit ={
println(a.getClass.getName)
}
}

上下文限定

  1. 语法
def f[A : B](a: A) = println(a) //等同于 def f[A](a:A)(implicit arg:B[A])=println(a)
  1. 说明
    上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定[A :Ordering]之后,方法内无法使用隐式参数名调用隐式参数,需要通过 implicitly[Ordering[A]]获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误。
implicit val x = 1
val y = implicitly[Int]
val z = implicitly[Double]

3、例子

def f[A:Ordering](a:A,b:A) =implicitly[Ordering[A]].compare(a,b)
def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/60984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023-8-31 Dijkstra求最短路(二)

题目链接&#xff1a;Dijkstra求最短路 II #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue>using namespace std;typedef pair<int, int> PII;const int N 150010;int n, m; int h[N…

解决 PaddleClas 下载预训练模型报错 ModuleNotFoundError No module named ‘ppcls‘ 的问题

当我们在使用 PaddleClas 进行预训练模型下载时&#xff0c;可能会遇到一个报错&#xff0c;报错信息为 ModuleNotFoundError: No module named ppcls。这个错误通常是因为 Python 解释器无法找到名为 ppcls 的模块&#xff0c;而我们的代码中正尝试导入它。让我们一起来解决这…

HTTP 代理原理及 Python 简单实现

HTTP 代理是一种网络代理服务器(Proxy Server),它能够作为客户端与 HTTP 服务器之间的中介,它的工作原理是: 当客户端向 HTTP 代理发送 HTTP 请求时,HTTP 代理会收到请求。 HTTP 代理会将请求转发给目标 HTTP 服务器。 目标 HTTP 服务器处理请求并生成响应。 HTTP 代理将…

什么是操作系统,数据结构

1、什么是操作系统&#xff1f; 操作系统是一组主管并控制计算机操作、运用和运行硬件、软件资源和提供公共服务来组织用户交互的相互关联的系统软件程序。根据运行的环境&#xff0c;操作系统可以分为桌面操作系统&#xff0c;手机操作系统&#xff0c;服务器操作系统&#x…

QT Creator工具介绍及使用

一、QT的基本概念 QT主要用于图形化界面的开发&#xff0c; QT是基于C编写的一套界面相关的类库&#xff0c;如进程线程库&#xff0c;网络编程的库&#xff0c;数据库操作的库&#xff0c;文件操作的库等。 如何使用这个类库&#xff1a;类库实例化对象(构造函数) --> 学习…

数据结构(Java实现)-二叉树(上)

树型结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根结点&…

Docker搭建elasticsearch+kibana测试

最近需要做大数据画像&#xff0c;所以先简单搭建一个eskibana学习使用&#xff0c;记录一下搭建过程和遇到的问题以及解决办法 1.拉取es和kibana镜像 在拉取镜像之前先搜索一下 elasticsearch发现是存在elasticsearch镜像的&#xff0c;我一般习惯性拉取最新镜像&#xff0c…

信息化发展12

数字民生 数字民生建设重点通常强调&#xff1a; 1 &#xff09; 普惠&#xff1a; 充分开发利用信息技术体系&#xff0c; 扩大民生保障覆盖范围&#xff0c; 助力普惠型民生建设&#xff0c; 解决民生资源配置不均衡等问题。 2&#xff09; 赋能&#xff1a; 信息技术体系与…

若依富文本 html样式 被过滤问题

一.场景 进入页面&#xff0c;富文本编辑框里回显这条新闻内容&#xff0c;如下图&#xff0c; 然后可以在富文本编辑框里对它实现再编辑&#xff0c;编辑之后将html代码提交保存到后台数据库。可以点击详情页进行查看。 出现问题&#xff1a;在提交到后台controller时&#x…

线程和进程的区别是什么?

线程(Thread)和进程(Process)是操作系统中两个重要的概念,用于管理程序的执行。它们有以下区别: 定义:进程:进程是程序的一个执行实例,它包含了程序的代码、数据以及执行上下文。进程是操作系统分配资源和调度的基本单位。线程:线程是进程的子执行单元,一个进程可以…

通过HTTP进行并发的数据抓取

在进行大规模数据抓取时&#xff0c;如何提高效率和稳定性是关键问题。本文将介绍一种可操作的方案——使用HTTP代理来实现并发的网页抓取&#xff0c;并帮助您加速数据抓取过程。 1. 选择合适的HTTP代理服务供应商 - 寻找信誉良好、稳定可靠且具备较快响应时间的HTTP代理服务…

单片机通用学习-​什么是寄存器?​

什么是寄存器&#xff1f; 寄存器是一种特殊的存储器&#xff0c;主要用于存储和检查微机的状态。CPU寄存器用于存储和检查CPU的状态&#xff0c;具体包括计算中途数据、程序因中断或子程序分支时的返回地址、计算结果为零时的负值、计算结果为零时的信息、进位值等。 由于CP…

相机SD卡数据丢失如何恢复?

出门在外&#xff0c;相机是人们记录生活点滴的重要工具&#xff0c;是旅游的最佳玩伴。人们每到一个地方&#xff0c;都喜欢用相机来见证自己来过的痕迹&#xff0c;拍好的照片都会被放到相机卡里&#xff0c;但在使用相机时&#xff0c;有时我们会意外删除了重要的照片或视频…

Plotlyjs 自定义日期坐标的格式 ,其中,如果上级单位与前一个坐标相同,则省略。

您可以定义一个自定义函数来格式化日期坐标&#xff0c;并在 tickformat 属性中使用它。以下是一个示例函数&#xff0c;它会检查上级单位是否与前一个坐标相同&#xff0c;并相应地省略。 function formatDateTick(value, index, values) {const d new Date(value);const pr…

微服务事务管理(Dubbo)

Seata 是什么 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。 一、示例架构说明 可在此查看本示例完整代码地址&#x…

第八周第四天学习总结

测试linux基础并复习基础命令

系统架构设计高级技能 · Web架构

现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 点击进入系列文章目录 系统架构设计高级技能 Web架构 一、Web架构介绍1.1 Web架构涉及技术1.2 单台服务…

springCloud整合Zookeeper的时候调用找不到服务

SpringCloud整合Zookeeper的时候调用找不到服务 首先&#xff0c;我们在注册中心注册了这个服务&#xff1a; 然后我们使用RestTemplate 调用的时候发现失败了&#xff1a;找不到这个服务&#xff1a; 找了很多资料发现这个必须要加上负载才行 BeanLoadBalanced //负载publi…

iOS开发Swift-闭包

1.闭包表达式语法 { (参数) -> return 类型 in//内容 }let names ["C", "A", "E", "B", "D"] func back(_ s1: String, s2: String) -> Bool {return s1 > s2 //(B > A, C > B) }//闭包后&#xff1a; va…

在CentOS7中,安装并配置Redis【个人笔记】

一、拓展——Ubuntu上安装Redis 输入命令su --->切换到root用户【如果已经是&#xff0c;则不需要进行该操作】apt search redis --->使用apt命令来搜索redis相关的软件包【查询后&#xff0c;检查redis版本是否是你需要的&#xff0c;如果不是则需要看看其他资料~】ap…