当前位置: 首页 > news >正文

Rust Trait 学习

概述

特征(trait)是rust中的概念,类似于其他语言中的接口(interface)。特征定义了一个可以被共享的行为,只要实现了特征,你就能使用该行为。
如果不同的类型具有相同的行为,那么我们就可以定义一个特征,然后为这些类型实现该特征。定义特征是把一些方法组合在一起,目的是定义一个实现某些目标所必需的行为的集合。例如,我们现在有圆形和长方形两个结构体,它们都可以拥有周长,面积。因此我们可以定义被共享的行为,只要实现了特征就可以使用。

pub trait Figure { // 为几何图形定义名为Figure的特征
fn girth(&self) -> u64; // 计算周长
fn area(&self) -> u64; // 计算面积
}

这里使用 trait 关键字来声明一个特征,Figure 是特征名。在大括号中定义了该特征的所有方法,在这个例子中有两个方法,分别是fn girth(&self) -> u64;和fn area(&self) -> u64;,特征只定义行为看起来是什么样的,而不定义行为具体是怎么样的。因此,我们只定义特征方法的签名,而不进行实现,此时方法签名结尾是 ;,而不是一个 {}。
接下来,每一个实现这个特征的类型都需要具体实现该特征的相应方法,编译器也会确保任何实现 Figure 特征的类型都拥有与fn girth(&self) -> u64;和fn area(&self) -> u64;签名的定义完全一致的方法。

Rust语言中的trait是非常重要的概念。在Rust中,trait这一个概念承 担了多种职责。很类似Go中的interface,但trait职责远比interface更多。trait中可以包含:函数、常量、类型等。

1,成员方法

们在特质中定义了一个成员方法,代码如下:

trait Shape {
fn area(&self) -> f64;
}

所有的trait中都有一个隐藏的类型Self(大写S),代表当前这个实 现了此trait的具体类型。

trait中定义的函数,也可以称作关联函数 (associated function)。

函数的第一个参数如果是Self相关的类型,且 命名为self(小写s),这个参数可以被称为“receiver”(接收者)。

具有 receiver参数的函数,我们称为“方法”(method),可以通过变量实例使 用小数点来调用。

没有receiver参数的函数,我们称为“静态函 数”(static function),可以通过类型加双冒号::的方式来调用。在 Rust中,函数和方法没有本质区别。

Rust中Self(大写S)和self(小写s)都是关键字,大写S的是类型名,小写s的是变量名。请大家一定注意区分。

self参数同样也可以指定类型,当然这个类型是有限制的,必须是包装在Self类型之上的类型。

对于第一个self参数,常见的类型有self:Self、self:&Self、self:&mut Self等类型。

对于以上这些类型,Rust提供了一种简化的写法,我们可 以将参数简写为self、&self、&mut self。self参数只能用在第一个参数的 位置。

请注意“变量self”和“类型Self”的大小写不同。比如:

trait T {
fn method1(self: Self);
fn method2(self: &Self);
fn method3(self: &mut Self);
}trait T {
fn method1(self);
fn method2(&self);
fn method3(&mut self);
}

我们可以为某些具体类型实现(impl)这个Shape trait。假如我们有一个结构体类型Circle,它实现了这个trait,代码如下:

trait Shape {
fn area(&self) -> f64;
}struct Circle {radius: f64,
}
impl Shape for Circle {// Self 类型就是 Circle// self 的类型是 &Self,即 &Circlefn area(&self) -> f64 {// 访问成员变量,需要用 self.radiusstd::f64::consts::PI * self.radius * self.radius}
}
fn main() {let c = Circle { radius : 2f64};// 第一个参数名字是 self,可以使用小数点语法调用println!("The area is {}", c.area());
}

另外,针对一个类型,我们可以直接对它impl来增加成员方法,无 须trait名字。比如:

impl Circle {fn get_radius(&self) -> f64 { self.radius }
}

我们可以把这段代码看作是为Circle类型impl了一个匿名的trait。用这种方式定义的方法叫作这个类型的“内在方法”(inherent methods)。

trait中可以包含方法的默认实现。如果这个方法在trait中已经有了 方法体,那么在针对具体类型实现的时候,就可以选择不用重写。

当然,如果需要针对特殊类型作特殊处理,也可以选择重新实现 来“override”默认的实现方式。比如,在标准库中,迭代器Iterator这个 trait中就包含了十多个方法,但是,其中只有fn next(&mut self)- >OptionSelf::Item是没有默认实现的。

其他的方法均有其默认实 现,在实现迭代器的时候只需挑选需要重写的方法来实现即可。

self参数甚至可以是Box指针类型self:Box。另外,目前Rust 设计组也在考虑让self变量的类型放得更宽,允许更多的自定义类型作为receiver,比如MyType。看下面的代码:

trait Shape {fn area(self: Box<Self>) -> f64;
}struct Circle {radius: f64,
}impl Shape for Circle {// Self 类型就是 Circle// self 的类型是 Box<Self>,即 Box<Circle>fn area(self : Box<Self>) -> f64 {// 访问成员变量,需要用 self.radiusstd::f64::consts::PI * self.radius * self.radius}
}fn main() {let c = Circle { radius : 2f64};// 编译错误// c.area();let b = Box::new(Circle {radius : 4f64});// 编译正确b.area();
}
//impl的对象甚至可以是trait。示例如下:trait Shape {fn area(&self) -> f64;
}trait Round {fn get_radius(&self) -> f64;
}struct Circle {radius: f64,
}impl Round for Circle {fn get_radius(&self) -> f64 { self.radius }
}// 注意这里是
impl Trait for Trait impl Shape for Round { //为满足T:Round的具体类型增加一个成员方法fn area(&self) -> f64 {std::f64::consts::PI * self.get_radius() * self.get_radius()}
}fn main() {let c = Circle { radius : 2f64};// 编译错误// c.area();let b = Box::new(Circle {radius : 4f64}) as Box<Round>;// 编译正确b.area();
}

impl Shape for Round和impl<T:Round>Shape for T是不一样的。

在前一种写法中,self是&Round类型,它是一个trait object,是胖指针。

而在后一种写法中,self是&T类型,是具体类型。

前一种写法是为trait object增加一个成员方法,而后一种写法是为所有的满足T:Round的具体类型增加一个成员方法。

所以上面的示例中, 我们只能构造一个trait object之后才能调用area()成员方法。
impl Shape for Round这种写法确实是很让初学者纠结的, Round既是trait又是type。在将来,trait object的语法会被要求加上dyn关键字。

2,静态方法

没有receiver参数的方法(第一个参数不是self参数的方法)称作“静态方法”。

静态方法可以通过Type::FunctionName()的方式调用。

需要注意的是,即便我们的第一个参数是Self相关类型,只要变量名字不是self,就不能使用小数点的语法调用函数。

struct T(i32);
impl T {
// 这是一个静态方法fn func(this: &Self) {println!{"value {}", this.0};}
}
fn main() {
let x = T(42);
// x.func(); 小数点方式调用是不合法的
T::func(&x);
}

在标准库中就有一些这样的例子。Box的一系列方法Box:: into_raw(b:Self)   Box::leak(b:Self),

以及Rc的一系列方法 Rc::try_unwrap(this:Self)Rc::downgrade(this:&Self),都是这种情况。
它们的receiver不是self关键字,这样设计的目的是强制用户 用Rc::downgrade(&obj)的形式调用,而禁止obj.downgrade()形 式的调用。

这样源码表达出来的意思更清晰,不会因为Rc里面的成员方法和T里面的成员方法重名而造成误解问题。

trait中也可以定义静态函数。下面以标准库中的std::default:: Default trait为例,介绍静态函数的相关用法:

pub trait Default {
fn default() -> Self;
}

上面这个trait中包含了一个default()函数,它是一个无参数的函 数,返回的类型是实现该trait的具体类型。Rust中没有“构造函数”的念。Default trait实际上可以看作一个针对无参数构造函数的统一抽象.比如在标准库中,Vec::default()就是一个普通的静态函数。

impl<T> Default for Vec<T> {
fn default() -> Vec<T> {
Vec::new()
}
}

跟C++相比,在Rust中,定义静态函数没必要使用static关键字,因 为它把self参数显式在参数列表中列出来了。

作为对比,C++里面成员 方法默认可以访问this指针,因此它需要用static关键字来标记静态方 法。

Rust不采取这个设计,主要原因是self参数的类型变化太多,不同写法语义差别很大,选择显式声明self参数更方便指定它的类型。

3,扩展方法

我们还可以利用trait给其他的类型添加成员方法,哪怕这个类型不 是我们自己写的。比如,我们可以为内置类型i32添加一个方法:

trait Double {
fn double(&self) -> Self;
}
impl Double for i32 {
fn double(&self) -> i32 { *self * 2 }
}
fn main() {
// 可以像成员方法一样调用
let x : i32 = 10.double();
println!("{}", x);
}

哪怕这个类型不是在当前 的项目中声明的,我们依然可以为它增加一些成员方法。

但我们也不是随随便便就可以这么做的,Rust对此有一个规定:

在声明trait和 impltraitl的时候,Rust规定CoherenceRule(一致性规则)或称为OrphanRule(孤儿规则):

imp块要么与trait的声明在同一个crate中,要么与类型的声明在同一个crate中。

这是有意的设计。如果我们在使用其他的crate的时候, 强行把它们“拉郎配”,是会制造出bug的。比如说,我们写了一个程 序,引用了外部库lib1和lib2,lib1中声明了一个trait T,lib2中声明了一 个struct S,我们不能在自己的程序中针对S实现T。这也意味着,上游开 发者在给别人写库的时候,尤其要注意,一些比较常见的标准库中的 trait,如Display Debug ToString Default等,应该尽可能地提供好。否 则,使用这个库的下游开发者是没办法帮我们把这些trait实现的。同理,如果是匿名impl,那么这个impl块必须与类型本身存在于同一个crate中。

Rust是一种用户可以对内存有精确控制能力的强类型语言。我们可 以自由指定一个变量是在栈里面,还是在堆里面,变量和指针也是不同 的类型。类型是有大小(Size)的。有些类型的大小是在编译阶段可以 确定的,有些类型的大小是编译阶段无法确定的。目前版本的Rust规 定,在函数参数传递、返回值传递等地方,都要求这个类型在编译阶段 有确定的大小。否则,编译器就不知道该如何生成代码了。 而trait本身既不是具体类型,也不是指针类型,它只是定义了针对 类型的、抽象的“约束”。不同的类型可以实现同一个trait,满足同一个 trait的类型可能具有不同的大小。因此,trait在编译阶段没有固定大小,目前我们不能直接使用trait作为实例变量、参数、返回值。比如:

let x: Shape = Circle::new(); // Shape 不能做局部变量的类型
fn use_shape(arg : Shape) {} // Shape 不能直接做参数的类型
fn ret_shape() -> Shape {} // Shape 不能直接做返回值的类型

这样的写法是错误的,请一定要记住。trait的大小在编译阶段是不固定的,需要写成dynShape形式,即编译的时候把不确定大小的东西通过胖指针来代替,而指针在编译期是确定的。

4,完整函数调用方法

Fully Qualified Syntax提供一种无歧义的函数调用语法,允许程序员精确地指定想调用的是那个函数。以前也叫UFCS(universal function call syntax),也就是所谓的“通用函数调用语法”。这个语法可以允许使用类似的写法精确调用任何方法,包括成员方法和静态方法。其他一切 函数调用语法都是它的某种简略形式。它的具体写法为::item。示例如下:

trait Cook {
fn start(&self);
}
trait Wash {
fn start(&self);
}
struct Chef;
impl Cook for Chef {
fn start(&self) { println!("Cook::start");}
}
impl Wash for Chef {
fn start(&self) { println!("Wash::start");}
}
fn main() {
let me = Chef;
me.start(); //error,出现歧义,编译其器不知道调用哪个方法
}//有必要使用完整的函数调用语法来进行方法调用
fn main() {
let me = Chef;
// 函数名字使用更完整的path来指定,同时,self参数需要显式传递 <Cook>::start(&me);
<Chef as Wash>::start(&me);
}

由此我们也可以看到,所谓的“成员方法”也没什么特殊之处,它跟 普通的静态方法的唯一区别是,第一个参数是self,而这个self只是一个 普通的函数参数而已。只不过这种成员方法也可以通过变量加小数点的 方式调用。变量加小数点的调用方式在大部分情况下看起来更简单更美 观,完全可以视为一种语法糖。
需要注意的是,通过小数点语法调用方法调用,有一个“隐藏 着”的“取引用”步骤。虽然我们看起来源代码长的是这个样子 me.start(),但是大家心里要清楚,真正传递给start()方法的参数是 &me而不是me,这一步是编译器自动帮我们做的。\color{red}不论这个方法接受 的self参数究竟是Self、&Self还是&mut Self,最终在源码上,我们都是 统一的写法:variable.method()。而如果用UFCS语法来调用这个方 法,我们就不能让编译器帮我们自动取引用了,必须手动写清楚。下面用一个示例演示一下成员方法和普通函数其实没什么本质区别。

struct T(usize);
impl T {
fn get1(&self) -> usize {self.0}
fn get2(&self) -> usize {self.0}
}
fn get3(t: &T) -> usize { t.0 }
fn check_type( _ : fn(&T)->usize ) {}
fn main() {
check_type(T::get1);
check_type(T::get2);
check_type(get3);
}

可以看到,get1、get2和get3都可以自动转成fn(&T)→usize类型。

5,trait 约束和继承

Rust的trait的另外一个大用处是,作为泛型约束使用。

未完待完善。。。

相关文章:

Rust Trait 学习

概述 特征&#xff08;trait&#xff09;是rust中的概念&#xff0c;类似于其他语言中的接口&#xff08;interface&#xff09;。特征定义了一个可以被共享的行为&#xff0c;只要实现了特征&#xff0c;你就能使用该行为。 如果不同的类型具有相同的行为&#xff0c;那么我们…...

基于开源链动2+1模式AI智能名片S2B2C商城小程序的爆品力构建研究

摘要&#xff1a;在兴趣电商生态中&#xff0c;爆品力已成为品牌实现指数级增长的核心竞争力。本文以开源链动21模式AI智能名片S2B2C商城小程序为技术载体&#xff0c;结合抖音平台的内容传播特性&#xff0c;提出“需求挖掘-技术赋能-内容转化”三位一体的爆品力构建模型。通过…...

【SimSession 】2:PacedReceiver:支持与 PacedVideoSender 本地联调

单独的基于libuv的发送能力,如何进一步在SimSession内集成使用?打算进行本地模拟俩线程,发送和接收,进行测试: 单独的发送测试 【SimSession】1:将视频发送逻辑与 libuv 事件循环集成是一个典型的并发设计问题 分析后,D:\XTRANS\thunderbolt\ayame\zhb-bifrost\player-…...

5 什么情况下需要微调

这个问题其实很重要&#xff0c;因为现代大模型训练出来已经非常强大&#xff0c;可能真的不需要微调。 我们可以通过 RAG 或提示词工程来实现目标。 需要微调的场景与替代方案分析 微调(Fine-tuning)确实不是所有场景都必需的&#xff0c;特别是考虑到现代大型语言模型(LLM…...

Docker 渡渡鸟镜像同步站 使用教程

Docker 渡渡鸟镜像同步站 使用教程 &#x1f680; 介绍 Docker.aityp.com&#xff08;渡渡鸟镜像同步站&#xff09;是一个专注于为国内开发者提供 Docker 镜像加速和同步服务的平台。它通过同步官方镜像源&#xff08;如 Docker Hub、GCR、GHCR 等&#xff09;&#xff0c;为…...

位图的实现和拓展

一&#xff1a;位图的介绍 ①&#xff1a;需要位图的场景 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中&#xff1f; 要判断一个数是否在某一堆数中&#xff0c;我们可能会想到如下方法&#xff1a; A…...

字符串问题c++

题目描述 小 Z 有一个字符串 s&#xff0c;他对这个字符串会进行如下两个操作&#xff1a; 1 p c 把字符串的第 p 个字符改成 c2 l r 把 s 的第 l 个字符到第 r 个字符按顺序输出。 这里『第 i 个字符』的下标计数从 1 开始&#xff0c;例如&#xff0c;a 是字符串 abc 的第…...

Redis事务

Redis中的事务是指提供一种将多个命令打包到一起&#xff0c;一次性按照顺序执行的机制。Redis在执行事务期间&#xff0c;不会接收处理其他操作命令。 Redis事务有以下局限性 无回滚机制&#xff1a;如果某个命令执行失败&#xff0c;不会影响其他命令的执行&#xff0c;因此…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】3.3 异常值识别(Z-score法/IQR法/业务规则法)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL数据分析实战&#xff1a;数据质量分析之异常值识别&#xff08;Z-score法 / IQR法 / 业务规则法&#xff09;3.3 异常值识别3.3.1 Z-score法3.3.2 IQR法3.3.3 业…...

MCP底层协议完整通信过程

2025 年是智能体的元年, 也注定是智能体集中爆发的一年! 两个互联领域的重大挑战: 第一、 Agent 与 Tools (工具)的交互 Agent 需要调用外部工具和 API...

C语言 指针(5)

目录 1.冒泡排序 2.二级指针 3.指针数组 4.指针数组模拟二级数组 1.冒泡排序 1.1 基本概念 冒泡排序&#xff08;Bubble Sort&#xff09; 是一种简单的排序算法&#xff0c;它重复地遍历要排序的数列&#xff0c;一次比较两个元 素&#xff0c;如果它们的顺序错误就把它…...

MYSQL-联合查询

经过上节课&#xff0c;我们学会了如何设计表以及了解到各种范式&#xff0c;这节课就请大家和小L一起来学习设计表之后如何使用 1.为什么要使用联合查询 在数据设计时由于范式的要求&#xff0c;数据被拆分到多个表中&#xff0c;那么要查询⼀个条数据的完整信息&#xff0c…...

一篇撸清 Http,SSE 与 WebSocket

HTTP,SSE 和WebSocket都是网络传输的协议,本篇快速介绍三者的概念和比较。 SSE(Server-Sent Events) 是什么? SSE(Server-Sent Events),服务器发送事件, 是一种基于 HTTP 的轻量级协议,允许服务器主动向客户端(如浏览器)推送实时数据。它设计用于单向通信(服务器到…...

系统架构设计师:设计模式——行为设计模式

一、行为设计模式 行为模式涉及算法和对象间职责的分配。行为模式不仅描述对象或类的模式&#xff0c;还描述它们之间的通信模式。这些模式刻画了在运行时难以跟踪的、复杂的控制流。它们将用户的注意力从控制流转移到对象间的联系方式上来。 行为类模式使用继承机制在类间分…...

OpenCV入门指南:从环境搭建到第一个图像处理程序

引言 你是否想让计算机"看懂"世界&#xff1f;OpenCV&#xff08;Open Source Computer Vision Library&#xff09;正是打开计算机视觉大门的钥匙。本文将带你从零开始搭建开发环境&#xff0c;理解图像处理核心概念&#xff0c;并完成第一个OpenCV程序。无论你是想…...

基于STM32的温湿度光照强度仿真设计(Proteus仿真+程序设计+设计报告+讲解视频)

这里写目录标题 **1.****主要功能****2.仿真设计****3.程序设计****4.设计报告****5.下载链接** 基于STM32的温湿度光照强度仿真设计(Proteus仿真程序设计设计报告讲解视频&#xff09; 仿真图Proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号…...

4个纯CSS自定义的简单而优雅的滚动条样式

今天发现 uni-app 项目的滚动条不显示&#xff0c;查了下原来是设置了 ::-webkit-scrollbar {display: none; } 那么怎么用 css 设置滚动条样式呢&#xff1f; 定义滚动条整体样式‌ ::-webkit-scrollbar 定义滚动条滑块样式 ::-webkit-scrollbar-thumb 定义滚动条轨道样式‌…...

修复笔记:SkyReels-V2项目中的 from_config 警告

#工作记录 Windows避坑部署SkyworkAI/SkyReels-V2昆仑万维电影生成模型_skyreels-v2本地部署-CSDN博客 一、项目背景 项目名称&#xff1a;SkyReels-V2 项目简介&#xff1a;由昆仑万维开源的全球首个无限时长电影生成模型&#xff0c;支持文本到视频、图像到视频等多种生成方…...

[硬件电路-11]:模拟电路常见元器件 - 什么是阻抗、什么是输入阻抗、什么是输出阻抗?阻抗、输入阻抗与输出阻抗的全面解析

1. 阻抗&#xff08;Impedance&#xff09; 定义&#xff1a;阻抗是电路或元件对交流信号&#xff08;AC&#xff09;流动的阻碍能力&#xff0c;用符号Z表示&#xff0c;单位为欧姆&#xff08;Ω&#xff09;。它综合了电阻&#xff08;R&#xff09;、电感&#xff08;L&am…...

MCP协议与Dify集成教程

一、MCP协议概述 MCP&#xff08;Model Control Protocol&#xff09;是一种新兴的开放协议&#xff0c;为大型语言模型&#xff08;LLM&#xff09;与外部应用之间构建了双向通信通道。它就像是AI的"USB-C"接口&#xff0c;帮助模型发现、理解并安全调用各种外部工…...

flink常用算子整理

文章目录 前言1.重新分配(即打散)2.合并流的算子3.算子链操作4.侧边输出(目前只有一种)5.键控进行分区6.输出算子7.其他基础操作算子8.其他常用的算子9.Flink窗口等情况10.窗口举例前言 提示:以下是本篇文章正文内容,下面案例可供参考 1.重新分配(即打散) 2.合并流的算子 3…...

【SimSession】1:将视频发送逻辑与 libuv 事件循环集成是一个典型的并发设计问题

之前对SimSession的信令进行测试,echo可以与relay联通,现在单独提取 已经集成了webrtc的发送模块及libuv框架与SimSession和echo集成: 采集、编码和发送之前在pacedsender内部实现的 现在从pacedsender中去掉采集、编码,放在session中运行。 而pacedsender仅暴露发送部分:…...

Circular Plot系列(五): circle plot展示单细胞互作

这是我们circle系列的最后一节&#xff0c;我想常见的弦图是绕不开的&#xff0c;所以最后从前面介绍的circle plot思路&#xff0c;做一遍弦图。其实前面的内容如果消化了&#xff0c;plot互作弦图也就不成什么问题了。 效果如下&#xff1a; #cellchat提取互作结果&#xff…...

LLama-v2 权重下载

地址&#xff1a;llama模型 官方github仓库&#xff1a;llama仓库 注意点 网络代理位置&#xff1a;美国下面的国家选择 United States 克隆仓库后 运行bash download.sh输入邮箱收到的URL选择要下载的权重等待下载完成即可 有问题留言&#xff01;&#xff01;&#xff01…...

深入解析Linux进程间通信(IPC):机制、应用与最佳实践

引言 在多任务操作系统中&#xff0c;进程间通信&#xff08;Inter-Process Communication, IPC&#xff09;是协同工作的核心机制。Linux作为现代操作系统的典范&#xff0c;提供了8种主要IPC方式&#xff0c;从传统的管道到面向网络的套接字&#xff0c;每种方法都暗藏独特的…...

基于开源AI大模型AI智能名片S2B2C商城小程序源码的私域流量稳定性构建研究

摘要&#xff1a;在私域流量时代&#xff0c;传统实体零售的"时间积累"逻辑被直播电商等新业态颠覆。完美日记等新锐品牌通过构建私域流量池&#xff0c;实现了从0到1的指数级增长&#xff0c;而传统品牌却陷入"流量焦虑"。本文提出以开源AI大模型AI智能名…...

第13章:陈默再访海奥华

第13章&#xff1a;陈默再访海奥华 第一节&#xff1a;启程——穿越虫洞的旅程 2046年&#xff0c;赤色世界的和平与繁荣达到了前所未有的高度。人类已经完成了从物质文明向意识文明的转变&#xff0c;精神力的普及让每一个人都拥有了学习、修复和感知的能力。然而&#xff0…...

Prompt compress 技术探究-LLMLingua2

LLMLingua2 https://arxiv.org/pdf/2403.12968是LLMLingua的改进版本。我们知道 LLMLingua需要用小模型压缩&#xff0c;模型太小不一定能保证性能&#xff0c;模型太大耗费时间又太长。这个方法理论上可以&#xff0c;但实际上不是很方便用。很难选择到合适的小模型。 小模型…...

【机器学习案列-22】基于线性回归(LR)的手机发布价格预测

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

python调用国税乐企直连接口开数电票之获取数字化电子发票批量预赋码信息

乐企平台介绍 乐企平台作为国家税务总局推出的唯一数电票标准化的API接口重要平台&#xff0c;旨在通过税务系统与企业自有信息系统的直连涉税服务&#xff0c;开票员登录企业自有系统&#xff08;ERP、OMS、发票管理系统等&#xff09;无需通过第三方平台即可实现国税直连开票…...

Axure打开html文件失败,解决方案:

1、在原型文件中找到 2、文件后缀名改为 axure-chrome-extension.rar ,解压后到axure-chrome-extension 3、打开Chrome浏览器&#xff0c;找到扩展程序 选择刚刚解压的文件axure-chrome-extension文件夹&#xff0c;配置完成&#xff0c;打开html试试吧...

Android第四次面试总结之Java基础篇(补充)

一、设计原则高频面试题&#xff08;附大厂真题解析&#xff09; 1. 单一职责原则&#xff08;SRP&#xff09;在 Android 开发中的应用&#xff08;字节跳动真题&#xff09; 真题&#xff1a;“你在项目中如何体现单一职责原则&#xff1f;举例说明。”考点&#xff1a;结合…...

网络开发基础(游戏)之 心跳机制

简介 心跳机制&#xff1a;是指客户端定时&#xff08;比如每隔着10秒&#xff09;向服务端发送PING消息&#xff0c;服务端收到后回应PONG消息。服务端会记录客户端最后一次发送PING消息的时间&#xff0c;如果很久没有收到下一次客户端发来的消息&#xff0c;服务端就就判…...

Hive进阶之路

目录 一、Hive 基础回顾 二、数据定义语言&#xff08;DDL&#xff09;进阶 2.1 复杂表创建 2.2 分区与分桶优化 三、数据操作语言&#xff08;DML&#xff09;深入 3.1 高效的数据加载 3.2 灵活的数据更新与删除 四、Hive 函数高级应用 4.1 内置函数的巧用 4.2 自定义…...

imx6uLL应用-v4l2

Linux V4L2 视频采集 JPEG 解码 LCD 显示实践 本文记录一个完整的嵌入式视频处理项目&#xff1a;使用 V4L2 接口从摄像头采集 MJPEG 图像&#xff0c;使用 libjpeg 解码为 RGB 格式&#xff0c;并通过 framebuffer 显示在 LCD 屏幕上。适用于使用 ARM Cortex-A 系列开发板进…...

以太坊智能合约开发框架:Hardhat v2 核心功能从入门到基础教程

一、设置项目 Hardhat 项目是安装了 hardhat 包并包含 hardhat.config.js 文件的 Node.js 项目。 操作步骤&#xff1a; ①初始化 npm npm init -y②安装 Hardhat npm install --save-dev hardhat③创建 Hardhat 项目 npx hardhat init如果选择 Create an empty hardhat.…...

【现代深度学习技术】现代循环神经网络06:编码器-解码器架构

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…...

Jasper and Stella: distillation of SOTA embedding models

摘要 Dense检索是许多深度学习应用系统中&#xff08;例如常见问题 &#xff08;FAQ&#xff09; 和检索增强生成 &#xff08;RAG&#xff09;&#xff09;关键组成部分。在此过程中&#xff0c;Embedding模型将原始文本转换为向量。然而&#xff0c;目前在文本Embedding基准…...

程序的本质—API接口

API 是什么 官方定义&#xff1a;API 英文全称 Application Programming Interface&#xff0c;翻译过来为程序之间的接口。也是程序与外部世界的桥梁&#xff0c;实现了服务拆分与解藕的核心机制 大白话&#xff1a;按照规则提供输入&#xff0c;它帮你得到对应的输出 API可…...

Python函数完全指南:从零基础到灵活运用

Python函数是组织代码、实现代码复用的基本单元&#xff0c;也是Python编程中最重要的概念之一。本文将全面介绍Python函数的知识体系&#xff0c;帮助初学者系统掌握函数的使用方法。 一、函数基础概念 1. 什么是函数&#xff1f; 函数是一段可重复使用的代码块&#xff0c…...

第十章.XML

文章目录 1.XMl简介2.解析XML技术2.1DOM解析XML 2.2DOM4j3.json 1.XMl简介 EXtensible Markup Language ,可扩充标记语言 特点: XML与操作系统,编程语言的开发平台无关实现不同系统之间的数据交换 作用: 数据交互配置应用程序和网站 XML标签 xml文档由一系列标签元素组成<…...

5个情感丰富GPT-4o图像提示词(不是吉卜力风格)

一场新的创意运动正在迅速兴起——人们不仅使用ChatGPT进行写作,还用它来构思富有想象力、情感丰富的视觉概念。 这一趋势正在改变我们讲故事、建立品牌和探索创意的方式。从异想天开的海报世界到基于物品的故事叙述,各行业的创作者正在将ChatGPT与视觉生成工具结合使用,赋…...

华为OD机试真题——求最多可以派出多少支队伍(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C、GO六种语言的最佳实现方式&#xff1b; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析&#xff1b; 本文收录于专栏&#xff1a;《2025华为OD真题目录…...

《七年一剑》速读笔记

文章目录 书籍信息概览知己知彼市场的本质认识自我了解他人人剑合一 技术分析精要K线分型均线节奏形态画线成交量周期级别指标之王——MACD波动理论 管窥基本面A股周期论实战角度看财报 构建交易系统打开交易之门交易基础之买卖依据风险控制与仓位管理系统评估及情绪管理 实战秘…...

VMware-centOS7安装redis分布式集群

1.部署redis包 1.1 在usr/local文件夹里创建文件夹 mkdir software 1.2 进入文件夹 cd /usr/local/software/ 下载redis wget http://download.redis.io/releases/redis-6.2.6.tar.gz解压 tar zxvf redis-6.2.6.tar.gz重命名文件夹 mv redis-6.2.6 redis安装gcc编译器 yum i…...

Kubernetes(k8s)学习笔记(六)--KubeSphere前置环境安装

1、安装 helm&#xff08;master 节点执行&#xff09; Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的apt、Centos 中使用的 yum 或者 Python 中的 pip 一样&#xff0c;能快速查找、下载和安装软件包。Helm由客户端组件 helm 和服务端组件 Tiller 组…...

黑马点评day01(基于Redis)

1.7 Redis代替session的业务流程 1.7.1、设计key的结构 首先我们要思考一下利用redis来存储数据&#xff0c;那么到底使用哪种结构呢&#xff1f;由于存入的数据比较简单&#xff0c;我们可以考虑使用String&#xff0c;或者是使用哈希&#xff0c;如下图&#xff0c;如果使用…...

14.Excel:排序和筛选

一 位置 两个位置。 二 排序&#xff1a;如何使用 1.常规使用 补充&#xff1a;不弹出排序提醒排序。 选中要排序列中的任意一个单元格&#xff0c;然后排序。 2.根据要求进行排序 1.根据姓名笔画进行降序排序 要勾选上数据包含标题&#xff0c;默认是勾选了。 2.根据运营部、…...

力扣-字符串-468 检查ip

思路 考察字符串的使用&#xff0c;还有对所有边界条件的检查 spilt&#xff08;“\.”&#xff09;&#xff0c;toCharArray&#xff0c;Integer.parseInt() 代码 class Solution {boolean checkIpv4Segment(String str){if(str.length() 0 || str.length() > 4) retur…...

C++名称空间

名称空间 名称空间可以是全局的&#xff0c;也可以位于另一个名称空间中&#xff0c;但不能位于代码块中。因此&#xff0c;在默认情况下&#xff0c;在名称空间中声明的名称的链接性为外部的&#xff08;除非它引用了常量&#xff09; 名称空间是开放的&#xff0c;你可以在…...