Scala中的隐式参数、隐式函数和隐式类

news2024/9/23 7:33:22

使用 implicit 修饰的内容是隐式内容, 隐式的特点就是遇到适应的类型会自动的应用。隐式可以使得静态类型动态化,为现有类库添加功能,隐式的代理增强一个类或者一个方法。

隐式转化的时机

  1. 当方法中的参数的类型与目标类型不一致时
  2. 当对象调用所在类中不存在的方法或成员时,编译器会自动将对象进行隐式转换

隐式参数

定义
使用 implicit 修饰的变量称为 隐式变量,对应的变量值为 隐式值。定义的函数列表中存在使用 implicit 修饰的参数,这个参数就是隐式参数。需要注意的是,隐式参数需要放在参数列表的最后面。

传参优先级
Scala中函数的传参级别:传参 > 隐式值 > 默认值
① 在调用函数时直接传参数值,就用该参数值。
② 若未传参数值,则优先使用与隐式参数相同类型的隐式变量的值。注意:同类型的隐式变量只能有一个。
③ 前两者都没有的话,就用该参数的默认值。

示例

// 第二个参数默认值为5
def sum(a:Int)(implicit b:Int = 5):Int = {
    a + b
}
// 第二个参数使用指定传值3
val m = sum(10)(3)
// 未指定第二个参数,传参数默认值5
val n = sum(10)
// 定义隐式变量,隐式值为10
implicit val num:Int = 10
// 第二个参数使用指定传值8
val p = sum(10)(8)
// 未指定第二个参数,传隐式值 10
val q = sum(10)

在这里插入图片描述

隐式函数

定义
使用 implicit 修饰的函数就是 隐式函数,也称为 隐式转换

应用场景
可以通过隐式函数将一种类型转换为另一种类型,主要用来做 类型转换类型增强 。输入 :implicit -v ,可查看Scala中定义的隐式函数和隐式类。
在这里插入图片描述

类型转换

当声明一个变量的类型与赋值类型不一致时,会直接报错,但若定义了一个可以将赋值类型转换为变量类型的隐式函数,则会自动对赋值类型做转换。
示例

// 报错:类型不匹配
val a:Int = 2.5
// 定义隐式参数
implicit def doubleToInt(dbl:Double) = dbl.toInt
// Double值会自动调用隐式转换,变为Int值
val b:Int = 2.5

类型增强

有些类型不能直接参与计算,比如Boolean,但若是给它做个隐式转换,就可以参与计算了。

// 报错:不能接受Boolean类型参与计算
val a = 1 + true
// 定义隐式函数
implicit def booleanToInt(bln:Boolean) = if(bln) 1 else 0
// true 转换为 1 false 转换为 0
val b = 1 + true

隐式类

定义
使用 implicit 修饰的类就是 隐式类。隐式类可以在不改变目标类型源代码的情况下,扩展目标类的功能。

约束

  1. 必须定义在trait/class/object里(不能独立定义)
  2. 构造器只能带一个不是implicit修饰的参数
  3. 作用域中不能有任何与隐式类同名的方法、成员或对象

示例

class B{
  val add = (x:Int, y:Int) => { x + y }
}
object ImplicitCtx{
  // 隐式类只能对一种类型的类进行增强,B类及其子类
  implicit class RichB(b:B){
    def multiply(x:Int, y:Int) = { x * y } 
  }
}
val b = new B
val m = b.add(2, 3)
// 引入隐式类后,就可以执行增强功能
import ImplicitCtx._
val n = b.multiply(2, 3)

在这里插入图片描述

隐式解析机制

即编译器是如何查找到缺失信息的,解析具有以下两种规则:

  1. 首先会在当前代码作用域下查找隐式实体(隐式方法 隐式类 隐式对象)
  2. 如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。

类型的作用域是指与该类型相关联的全部伴生模块,一个隐式实体的类型T它的查找范围如下:

  • 如果T被定义为T with A with B with C,那么A,B,C都是T的部分,在T的隐式解析过程中,它们的伴生对象都会被搜索。
  • 如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分,比如List[String]的隐式搜索会搜索List的伴生对象和String的伴生对象
  • 如果T是一个单例类型p.T,即T是属于某个p对象内,那么p对象也会被搜索
  • 如果T是类型注入S#T,那么S和T都会被搜索

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

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

相关文章

HOT18-矩阵置零

leetcode原题链接: 矩阵置零 题目描述 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,…

【Flutter】Flutter Redux 入门:解决状态管理的问题

文章目录 一、 前言二、 Flutter Redux 简介1. 什么是 Redux2. 为什么需要 Redux3. Flutter Redux 的作用 三、 Flutter Redux 的基本使用1. 安装和配置2. 创建 Store3. 使用 StoreProvider 四、 Flutter Redux 的基础示例1. 创建一个简单的计数器应用2. 解析代码和说明 五、 版…

解决npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher

一、问题 环境 系统:centos 7 node :v18.16.1 npm:9.5.1 安装pm2 npm install -g pm2提示报错: npm WARN deprecated uuid3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certai…

记录react 视频和 预览拖动

一、react 视频 ##1、循环播放 import React, { useEffect, useState, useRef } from "react"; const videoRef useRef(null); const showVideoClass { display: "block", width: "100%", height: "100%" } const hindVideoClass …

Zookeeper的应用场景

一、Zookeeper的应用场景包括: 配置中心:Zookeeper可以用来存储和管理配置信息,例如集群中的机器配置、服务地址配置等。通过Zookeeper,可以将配置信息统一管理,同时实现动态加载和更新。统一命名服务:Zoo…

Ubuntu 20.04.02 LTS安装virtualbox7.0

ubuntu22.04的软件仓库也有virtualbox,不过版本较老。 使用安装命令:sudo apt install virtualbox 如果想要安装最新版,那么需要去官网下载deb包或者使用官方的仓库。 这里采用安装Oracle官方仓库的方法。 执行如下命令: wge…

fastadmin 点击获取当前行数据

fastadmin 点击获取当前行数据 // 先获取当前id // 使用方法的语法:$(#table).bootstrapTable(method, parameter);$(document).on("click",".detailtips",function(){var ids$(this).attr("id");var rows$("#table").boo…

pytorch快速入门中文——04(训练图片分类器)

训练分类器 原文:https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py 就是这个。 您已经了解了如何定义神经网络,计算损失并更新网络的权重。 现在您可能在想, 数据呢&…

java小技能:分布式任务调度平台

文章目录 引言I 报表数据生成II 注意事项2.1 任务创建2.2 pom.xml 添加到maven项目 see also 引言 任务调度的应用场景: 生成日报、月报、定时处理任务(定期清理文件、处理数据) I 报表数据生成 https://kunnan.blog.csdn.net/article/deta…

你知道GPT-3带的即时学习能力是什么吗

你知道GPT-3带的即时学习能力是什么吗 在人工智能领域,GPT-3(Generative Pre-trained Transformer 3)是当前比较先进的自然语言处理模型之一。它采用了自监督学习的方式进行训练,并且拥有强大的“in-context learning”&#xff…

nginx-rewrite

目录 1.rewrite 2.应用场景 3.跳转实现及特点 4.格式 5.location分类 6.具体应用场景 1.基于域名跳转 2.基于客户端ip访问跳转 3.基于旧域名跳转新域名后加的目录 4.基于匹配的跳转 5.基于目录下所有php结尾文件跳转 6.基于最普通一条url请求的跳转 7.总结 1.rewrite 重…

星辰秘典:揭开Python项目的神秘密码——2048游戏

✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(html css js) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:你好&#x…

Docker 部署 jar 项目

文章目录 1、上传jar包2、新建 Dockerfile 文件3、新建 deploy.sh 脚本(创建并运行)4、新建 upgrade.sh 脚本(更新) 1、上传jar包 2、新建 Dockerfile 文件 添加jar包及修改端口 # 基础镜像 FROM java:8 # 添加jar包 ADD servic…

百度智能车竞赛丝绸之路智能车设计与编程实现控制

一、项目简介 本项目现已基于鲸鱼机器人开发套件对其整体外形进行设计,并且对应于实习内容——以“丝绸之路”为题,对机器人各个功能与机器人结构部分进行相关设计与调整。主要可以实现“车道线巡检”“音乐交际”、“城堡检测”、“翻山越岭”。 本项…

Java使用策略模式和工厂模式来消除冗余的if-else语句(UML类图+案例+提供Gitee源码)

前言:在最近的后端开发中,多多少少会发现有很多if-else语句,如果条件过多则会造成整体代码看起来非常臃肿,这边我就举一个我在实际开发中的例子,来进行阐述这两种模式在实际开发中我是如何运用的。 目录 一、工厂模式…

把Jar打包为Maven 把jar打包为maven 将java项目打包为maven 将Java项目打包为Maven

把Jar打包为Maven 把jar打包为maven 将java项目打包为maven 将Java项目打包为Maven 自己写了一个通用SDK Jar包,但是现在的项目都是Maven项目,需要把Jar打包为Maven格式,输出到本地Maven仓库,在项目中可以引用查看Maven是否安装打…

nginx进行反向代理

Nginx是一个开源的高性能Web服务器和反向代理服务器。它最初是由Igor Sysoev在2004年开发的,现在由一个全球性的社区维护和支持。 Nginx的主要特点包括: 高性能:Nginx使用事件驱动模型,可以处理高并发请求,具有出色的…

A* 算法研究(附 Python / C++ 实现)

A* 算法研究 参考 A*寻路算法详解 #A星 #启发式搜索 路径规划之 A* 算法 最短路搜索-从Dijkstra到Best-First再到A-Star 路径规划算法学习笔记(一):A*算法 A*算法寻路(C代码实现) 《基于A*算法的自动泊车全局路径规划…

恒生电子联合恒生聚源发布数智金融新品,聚焦大模型技术金融业务应用

6月28日,恒生电子和旗下子公司恒生聚源正式发布基于大语言模型技术打造的数智金融新品,金融智能助手光子和全新升级的智能投研平台WarrenQ。此外,恒生电子金融行业大模型LightGPT也首次对外亮相,并公布最新研发进展。 恒生电子董…

升级Win10后多了个恢复分区,有什么用

很多用户从Win7/Win8/Win8.1升级到Win10之后发现电脑硬盘上多出了一个“恢复分区”,64位系统下这个分区大小在450MB左右。那么为什么会多出这样一个分区,这个分区又是干什么的,能不能删除呢?下面以MBR硬盘情况为例来说明。 1.全盘…