Scala学习笔记19: 隐式转换和隐式参数

目录

    • 第十九章 隐式转换和隐式参数
      • 1- 隐式转换
        • 1. 隐式准换函数: 施展魔法的咒语
        • 2. 隐式类: 为已有类型添加魔法
        • 3. 隐式转换规则: 魔法生效的条件
        • 4. 举例说明: 见证魔法的时刻
        • 5. 注意事项: 谨慎使用魔法
      • 2. 隐式参数
        • 1. 语义: 隐藏在背后的参数
        • 2. 使用 隐式参数的方式
          • 2.1 隐式值: 预先定义的助手
          • 2.2 隐式参数列表: 按需传入
        • 3. 优点: 简洁、灵活 、可扩展
        • 4. 注意事项
        • 5. 总结
      • end

第十九章 隐式转换和隐式参数

隐式转换和隐式参数是 Scala 中两个强大的特性, 它们可以使代码更简洁、更灵活, 但也容易造成理解上的困难 ;

隐式转换 允许你自动将一种类型的对象转换成另一种类型的对象, 而无需显式调用转换方法 ;

例如, 你可以定义一个隐式转换, 将整数自动转换为字符串 ;

隐式参数 则允许你在函数定义中忽略某些参数, 编译器会在调用函数时自动查找并传入这些参数 ;

例如, 你可以定义一个隐式参数, 用于表示数据库连接, 并在需要访问数据库的函数中使用它 ;

总而言之, 隐式转换和隐式参数都可以帮助你简化代码, 提高代码的复用性 ; 但是, 过渡使用它们可能会使代码难以理解和调试 ;

因此, 在使用它们时需要谨慎, 并遵循一些最佳实践, 例如:

  • 尽量将隐式隐式转换和隐式参数的定义放在伴生对象中, 以便于管理和查找 ;
  • 使用清晰易懂的命名来定义隐式转换和隐式参数 ;
  • 避免定义过于复杂的隐式转换和隐式参数, 以避免造成代码难以理解 ;

1- 隐式转换

Scala中的隐式转换就像魔术师手中的魔法棒, 可以在不改变代码结构的情况下, 悄无声息地将一种类型的值转换为另一种类型 ;

1. 隐式准换函数: 施展魔法的咒语

隐式转换函数式实现隐式转换的核心机制 ; 它们就像魔法咒语, 只要轻轻念动, 就能将目标悄悄改变 ;

要定义一个隐式转换函数, 你需要使用 implicit 关键字 :

implicit def intToString(x: Int): String = x.toString
2. 隐式类: 为已有类型添加魔法

隐式类是 Scala 2.10 版本引入的新特性, 它提供了一种更简洁的方式来扩展现有类型的功能 ;

  implicit class RichInt(val value: Int) extends AnyVal {def times(n: => Int): Int = value * n}println(2 times 3) // Output: 6

上面的代码定义了一个名为 RichInt 的隐式类, 它为 Int 类型添加了一个 times 方法 ;

隐式类必须定义在其它类、对象或包中, 并且只能有一个参数 .

3. 隐式转换规则: 魔法生效的条件

Scala 编译器在以下情况下会尝试应用隐式转换:

  • 当表达式类型与预期类型不匹配时 ;
  • 当调用对象上不存在的方法时 ;

在寻找合适的隐式转换时, 编译器会遵循一定的规则:

  • 首先查找当前作用域内的隐式转换 ;
  • 如果没有找到, 则会查找伴生对象中的隐式转换 ;
  • 最后, 还会查找导入的隐式转换 ;
4. 举例说明: 见证魔法的时刻
  implicit class RichInt(val value: Int) extends AnyVal {def times(n: => Int): Int = value * n}def main(args: Array[String]): Unit = {// 隐式函数implicit def intToString(x: Int): String = x.toString// 隐式转换函数示例val num: Int = 10val str: String = num // 编译器会自动应用 intToString 函数进行转换println(str) // Output: 10// 隐式类val result: Int = 10.times(2) // 编译器会自动应用 RichInt 类的 times 方法进行转换println(result) // Output: 20}
5. 注意事项: 谨慎使用魔法

隐式转换虽然强大, 但也要谨慎使用 ; 过渡使用隐式转换会导致代码难以理解和维护 ;

  • 尽量将隐式转换定义在伴生对象中, 并为其取一个清晰易懂的名称 ;
  • 避免定义过于复杂的隐式转换 ;

总而言之, 隐式转换是 Scala 中一个强大而灵活的机制, 可以使代码更加简洁和易读 ; 但要切记, 谨慎使用 !

2. 隐式参数

Scala 隐式参数就像一双无形的助手, 它可以在无需显示传递参数的情况下, 默默地为函数提供所需的值 ;

1. 语义: 隐藏在背后的参数

在函数定义中, 使用 implicit 关键字标记的参数被称为 隐式参数 ;

当调用带有隐式参数的函数时, 如果未提供该参数, 编译器会尝试在当前作用域内查找一个类型匹配的隐式值, 并自动将其传入函数 ;

  def greet(name: String)(implicit greeting: String): Unit = {println(s"$greeting, $name")}def main(args: Array[String]): Unit = {// 隐式参数greet("Jim")("Hello") // Output: Hello, Jim}

在上面的代码中, greeting 是一个隐式参数 ;

2. 使用 隐式参数的方式
2.1 隐式值: 预先定义的助手

可以通过定义一个 implicit val 来提供隐式值 :

  def greet(name: String)(implicit greeting: String): Unit = {println(s"$greeting, $name")}def main(args: Array[String]): Unit = {implicit val defaultGreeting = "Hello"greet("Jim") // 等同于: greet("Jim")(defaultGreeting)// Output: Hello, Jim

编译器会自动使用 defaultGreeting 的值作为 greeting 参数 ;

2.2 隐式参数列表: 按需传入

可以在函数定义中添加一个隐式参数列表, 并在其中声明需要的隐式参数类型 :

  def connect(implicit database: Database): Unit = {// 使用 database 链接数据库}

调用 connect 函数时, 编译器会在当前作用域内寻找类型为 Database 的隐式值 ;

3. 优点: 简洁、灵活 、可扩展
  • 简化代码: 避免重复传递相同的参数 ;
  • 提高灵活性: 可以在不同的上下文中使用不同的隐式值 ;
  • 增强可扩展性: 可以轻松地添加新的隐式值, 而无需修改现有代码 ;
4. 注意事项
  • 作用域要清晰: 隐式参数的查找范围有限, 确保其在作用域内可见 ;
  • 避免歧义: 避免定义多个类型相同的隐式值, 导致编译器无法确定使用哪个 ;
  • 谨慎使用: 过度使用隐式参数会降低代码的可读性和可维护性 ;
5. 总结

Scala 隐式参数是一项强大的功能, 可以使代码更简洁、更灵活, 但也需要谨慎使用 ;

理解其工作原理和最佳实践, 才能更好地驾驭它 .

end

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

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

相关文章

秒懂设计模式--学习笔记(11)【结构型-享元模式】

目录 10、享元模式10.1 享元模式10.2 举例10.2.1 马赛克10.2.2 游戏地图(以草原地图作为范例) 10.3 总结 10、享元模式 10.1 享元模式 “享元”则是共享元件的意思享元模式的英文flyweight是轻量级的意思,这就意味着享元模式能使程序变得更…

stack(leetcode练习题)

文章目录 STL用法总结32 最长有效括号思路代码 496 下一个最大元素思路代码 856 括号的分数思路 STL用法总结 关于stack的知识,可以看点击查看上面的博客,以下题目全在leetcode 32 最长有效括号 思路 “(()” “()(()” “(()(((()” 最开始写的&…

Linux下docker快速安装gitea

之前在服务器上装的gitlab来管理个人项目,但是gitlab服务启动后能明显感受到占用资源比较严重。最近服务器到期,换了个服务器还没来得及装gitlab,刚好最近接触到gitea,网上是这么说的 占用资源少,适合个人开发者&…

[PM]数据分析

概览 数据的定义 运营数据 分析的目的 数据分析流程 1.明确目标 2.数据来源 3.采集数据 4.数据整理 5.数据分析 趋势分析 当数据出现异常,一般从3个角度去查找问题: 1.技术层面,是不统计出错,或者产品出现bug 工 2.产品层面&am…

连接hive库增加相关包

连接hive库增加相关包 例如:java.lang.NoClassDefFoundError: com/ctc/wstx/io/InputBootstrapper org.apache.hadoop.hive.common.auth.HiveAuthUtils java.lang.NoClassDefFoundError: org/codehaus/stax2/XMLInputFactory2

0711springNews新闻系统管理 实现多级评论

0611springmvc新闻系统管理-CSDN博客 0711springNews新闻系统管理项目包 实现多级评论-CSDN博客 数据库字段 需要添加父节点id,通过该字段实现父评论和子评论的关联关系。 对象属性 实现链表,通过一个父评论可以找到它对应的所有子孙评论。 业务层 实现…

Capture软件元件库(以STM32为例)

本教程基于【凡亿】Cadence Allegro 17.4零基础入门66讲PCB Layout设计实战视频 (一)自带库路径查找 1,首先在找到文件的快捷方式 2,右键打开文件所在位置 3,点击tools(上一级目录) 4&#xf…

Docker 和 k8s 之间是什么关系?

Docker 简介 Docker 功能: Docker 是一款可以将程序和环境打包并运行的工具软件。通过 Docker,可以将程序及其依赖环境打包,确保在不同操作系统上一致的运行效果。 环境一致性问题: 程序依赖于特定的环境,不同操作系统…

数据库系列

目录 一、数据库的概念和作用 1.数据库的特点 2.数据模型 二、数据库系统 1.数据库管理系统 2.数据库的基本操作 一、数据库的概念和作用 数据库是指长期存储在计算机内,有组织的、可共享的数据集合。它可视为一个电子化的文件柜,用来存储电子文件…

数据库最佳实践:优化爬虫管理的数据存储方案

摘要: 面对日益增长的数据抓取需求,如何高效管理和存储爬虫获取的海量信息成为一大挑战。本文将深入探讨数据库最佳实践,揭示如何通过优化策略提升爬虫数据存储效率,助您跨越数据管理的障碍,实现数据价值最大化。 一、…

Mac上安装Charles 对iPhone进行抓包

Mac上安装Charles 对iPhone进行抓包 Charles 对手机抓包,如果步骤已经完全了但是上不了网,多半是因为证书没有添加信任,需要在两个地方进行设置: 在mac上,启动台>钥匙串访问>找到自己安装的证书 进行设置 ios的…

SpringBoot+Vue(3)Excel的在线预览

一、思路 在Spring Boot和Vue.js的组合中实现Excel文件的在线预览功能,通常涉及到几个关键步骤:文件上传、文件存储、文件读取、以及通过前端展示Excel内容。由于Excel文件本身不是直接可以在网页上渲染的格式,我们通常需要将Excel文件转换为…

SpringMVC源码深度解析(下)

接着上一遍博客《SpringMVC源码深度解析(中)》继续聊。上一篇博客中,返回的是对象的情况下SpringMVC框架会怎么处理,这种情况也是现在用得最多的,因为都是前后端分离。如果返回的是ModelAndView,则是另外的处理逻辑了,…

稀疏支持向量机(Sparse Support Vector Machine, Sparse SVM)

稀疏支持向量机(Sparse Support Vector Machine, Sparse SVM) 稀疏支持向量机是一种在支持向量机的基础上,通过引入稀疏性约束,使得模型参数更加稀疏,从而提高模型的可解释性和计算效率的方法。以下是稀疏支持向量机的…

CSS3 教程

CSS3 教程 引言 CSS3,即层叠样式表的第三代,是网页设计和开发中不可或缺的技术之一。它为HTML元素提供了丰富的样式定义,使得网页不仅内容丰富,而且外观美观、交互性强。本教程将详细介绍CSS3的基础知识、高级特性以及最佳实践&…

【Spring Boot 中的 `banner.txt` 和 `logback-spring.xml` 配置】

文章目录 一、banner.txt1. 创建自定义 banner.txt2. 配置 banner.txt 的内容 二、logback-spring.xml1. 创建 logback-spring.xml2. 配置 logback-spring.xml 一、banner.txt banner.txt 是 Spring Boot 项目启动时显示的自定义横幅内容。用来展示项目名称、版本信息或者其他…

python实现计数排序、桶排序和基数排序算法

python实现计数排序、桶排序和基数排序算法 计数排序算法步骤: Python实现计数排序桶排序算法步骤: Python实现桶排序基数排序算法步骤: Python实现基数排序算法时间复杂度 计数排序 计数排序是一种非比较排序算法,适用于元素范围…

数据仓库中事实表设计的关键步骤解析

在数据仓库的设计过程中,事实表是描述业务度量的核心组件。本文将深入探讨数据仓库中事实表设计的关键步骤,包括选择业务过程及确定事实表类型、声明粒度、确定维度和确定事实的过程,帮助读者更好地理解和应用事实表设计的原则和方法。 第一…

Ideal窗口中左右侧栏消失了

不知道大家在工作过程中有没有遇到过此类问题,不论是Maven项目还是Gradle项目,突然发现Ideal窗口右侧图标丢失了,同事今天突然说大象图标不见了,不知道怎样刷新gradle。 不要慌张,下面提供一些解决思路: 1…

【C语言ffmpeg】打开第一个视频

文章目录 前言须知ffmpeg打开文件基本流程图ffmpeg打开媒体文件AVFormatContext *avformat_alloc_context(void);AVFormatContext 成员变量及其作用AVInputFormat *iformatAVOutputFormat *oformatvoid *priv_dataAVIOContext *pbunsigned int nb_streamsAVStream **streamscha…