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

2311rust特征

Rust无成本抽象

Rust中抽象基石是trait:
1,TraitRust中唯一的接口概念.多个类型可实现一个特征,事实上,可为现有类型提供新的特征实现.另一方面,想抽象未知类型时,找特征就行了.
2,与C++模板一样,可静态分发特征.
3,可动态分发特征.有时确实需要间接,所以不必运行时"擦除"抽象.想运行时分发时,可使用接口特征.

背景:Rust中的方法

Rust提供了方法自由函数,它们密切相关:

struct Point {x: f64,y: f64,
}
//把(借用的)点转换为串的`自由`函数
fn point_to_string(point: &Point) -> String { ... }
//"固有的`impl"`块,直接在`类型`上定义了可用的方法
impl Point {//此方法在`Point`上都可用,并自动借用`Point`值fn to_string(&self) -> String { ... }
}

上述to_string方法叫"固有"方法,因为它们:
1,(通过impl)绑定到单个具体的"self"类型.
2,在该类型值上自动可用.也即,与函数不同,内置方法总是"在域内".

方法第一个参数总是是显式的"self",根据期望的所有权级别,它是self,&mut self&self.使用.调用方法.
self参数,按方法中使用的self形式隐式借用:

let p = Point { x: 1.2, y: -3.7 };
let s1 = point_to_string(&p);  //显式借用,调用自由函数.
let s2 = p.to_string();        //按`&p`隐式借用,来调用方法

如下,流式生成进程的API:

let child = Command::new("/bin/cat").arg("rusty-ideas.txt").current_dir("/Users/aturon").stdout(Stdio::piped()).spawn();

特征是接口

接口允许每个代码自由切换.对特征,规范主要围绕方法展开.
如,以下用来哈希的简单特征:

trait Hash {fn hash(&self) -> u64;
}

为了为给定类型实现此特征,必须提供匹配签名的哈希方法:

impl Hash for bool {fn hash(&self) -> u64 {if *self { 0 } else { 1 }}
}
impl Hash for i64 {fn hash(&self) -> u64 {*self as u64}
}

Java,C#Scala等语言中的接口不同,可为现有类型实现新特征(如上面的Hash).即可在事后创建抽象,并应用至现有库.

内置方法不同,仅当特征在域时,特征方法才在域中.但是假设Hash在域内,你可编写true.hash(),因此实现一个特征扩展了类型上可用的方法集.
定义和实现特征不过是抽象多个类型满足的通用接口.

静态分发

一般通过泛型消费特征:

fn print_hash<T: Hash>(t: &T) {println!("The hash is {}", t.hash())
}

在未知T类型上,print_hash函数是泛型函数,但要求T实现Hash特征.即可与booli64值一起,使用它:

print_hash(&true);      //实例化`T=bool`
print_hash(&12_i64);    //实例化`T=i64`

静态分发中编译掉泛型.也即,与C++模板一样,编译器生成print_hash方法的两个副本来处理上述代码,每个副本对应一个具体参数类型.

反之表明内部调用t.hash()(实际使用抽象点)的成本为零:按直接静态调用相关实现编译它:

//编译后的代码:直接调用特化`bool`版本
__print_hash_bool(&true);  //
__print_hash_i64(&12_i64);   
//直接调用特化`i64`版本

对像print_hash类函数,该编译模型不是很有用,但对更实际的哈希使用,却非常有用.假设还引入了一个相等比较特征:

trait Eq {fn eq(&self, other: &Self) -> bool;
}

这里按实现trait的类型解析Self的引用;在impl Eq for bool中,它引用bool.
然后,可定义一个在实现哈希EqT类型上是都通用的哈希映射:

struct HashMap<Key: Hash + Eq, Value> { ... }

泛型静态编译模型有几个好处:
1,对具体的KeyValue类型,每次使用HashMap都会产生不同的具体HashMap类型,即HashMap可在其存储桶内联(无间接)布局键和值.
来可节省空间和间接,并提高缓存局部性.

2,HashMap上的每个方法同样会生成特化代码.即,如上,调用哈希Eq,不会产生额外成本.表明优化器可用最具体(也即没有抽象)的代码.
特别是,静态分发允许在泛型用法间内联.
总之,与在C++模板一样,你可用泛型编写无成本的相当高级的抽象.
但是,与C++模板不同的是,会提前完全类型检查特征客户.也即,单独编译HashMap时,会根据抽象HashEq特征检查一次代码类型正确性,而不是在每当应用具体类型时的重复检查.

即库作者可更早,更清晰地出现编译错误,而客户类型检查成本更少(即编译速度更快).

动态分发

有时,抽象不仅是重用或模块化,有时在运行时不能去掉抽象.
如,GUI框架一般涉及响应事件(如点击鼠标)的回调:

trait ClickCallback {fn on_click(&self, x: i64, y: i64);
}

GUI元素,常见的是,允许为单个事件注册多个回调.对泛型,可想象这样写:

struct Button<T: ClickCallback> {listeners: Vec<T>,...
}

但问题立即显现出来:即每个按钮都按ClickCallback一个实现特化,且按钮类型反映了该类型.这不是想要的!

相反,想要一个带一组每个都可能是不同具体类型,但都实现了ClickCallback异构监听器的Button类型.
难点是,如果是一组异构类型,则每个类型都有不同的大小,则如何才能布局内部向量?答案一般是:间接.在向量存储回调指针:

struct Button {listeners: Vec<Box<ClickCallback>>,...
}

在此,就像它是一个类型一样,使用ClickCallback特征.在Rust中,特征类型,但它们是"无大小的",只允许出现在Box(指向堆)或&(可任意指向)等指针后面.

Rust中,像&ClickCallbackBox<ClickCallback>的类型叫"trait对象",它包括指向实现ClickCallbackT类型实例的指针,及一个虚表:一个指向T对trait每个方法实现的指针(这里,只是on_click).
可在运行时用该信息正确分发调用方法,并确保统一表示T.因此,只编译一次Button.

多用途

1,闭包.

类似ClickCallback特征,Rust中的闭包只是特定特征.深入

2,条件API.泛型可有条件地实现特征:

struct Pair<A, B> { first: A, second: B }
impl<A: Hash, B: Hash> Hash for Pair<A, B> {fn hash(&self) -> u64 {self.first.hash() ^ self.second.hash()}
}

在此,仅当组件实现Hash时,Pair类型才实现Hash,但允许在不同环境中使用单个Pair类型,这样最大化支持每个环境API的可用性.

这在Rust中很常见,因此内置了.

#[derive(Hash)]
struct Pair<A, B> { .. }

3,扩展方法.可用Traits使用新方法扩展(在其他地方定义的)现有类型,类似C#的扩展方法.只需在特征中定义新方法,为相关类型提供实现,就可用该方法.

4,标记.Rust有一些"标记类型":发送,同步,复制,调整(Send, Sync, Copy, Sized).这些标记只是带空体的特征,然后可在泛型和特征对象中使用.

可在库中定义标记,它们会自动提供#[derive]风格实现:如,如果所有子类型都是Send,则类型也是.如前,这些标记可能非常强大:发送(Send)标记是Rust保证线安的方式.

5,重载.Rust不支持用多个签名定义相同方法的传统重载.但是trait提供了重载的大部分好处:如果在trait泛型定义了方法,则实现该trait的类型都可调用它.

传统重载相比,有两个优点.首先,即重载不是临时的:一旦理解一个特征,就会立即理解使用它的API重载模式.
其次,它是可扩展的:通过提供新的特征实现,可有效地在方法下游提供新的重载.

6,符号.Rust允许在自己类型上重载+等符号.由相应标准库特征定义每个符号,实现该特征类型也会自动提供符号.

相关文章:

2311rust特征

Rust无成本抽象 Rust中抽象基石是trait: 1,Trait是Rust中唯一的接口概念.多个类型可实现一个特征,事实上,可为现有类型提供新的特征实现.另一方面,想抽象未知类型时,找特征就行了. 2,与C模板一样,可静态分发特征. 3,可动态分发特征.有时确实需要间接,所以不必运行时"擦除…...

原型模式 rust和java的实现

文章目录 原型模式介绍优点缺点使用场景 实现java 实现rust 实现 rust代码仓库 原型模式 原型模式&#xff08;Prototype Pattern&#xff09;是用于创建重复的对象&#xff0c;同时又能保证性能。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当…...

阿里云ACK(Serverless)安装APISIX网关及APISIX Ingress Controller

在k8s上安装apisix全家&#xff0c;通过helm安装很简单&#xff0c;但是会遇到一些问题。 安装 首先登录阿里云控制台&#xff0c;在ACK集群详情页&#xff0c;进入CloudShell&#xff0c;执行下面helm命令安装apisix、apisix-ectd、apisix-dashboard和apisix-ingress-contro…...

vue+mongodb+nodejs实现表单增删改查

ExpressMongodbVue实现增删改查 效果图 前言 最近一直想学下node,毕竟会node的前端更有市场。但是光看不练&#xff0c;感觉还是少了点什么&#xff0c;就去github上看别人写的项目&#xff0c;收获颇丰&#xff0c;于是准备自己照葫芦画瓢写一个。 作为程序员&#xff0c;一…...

SpringBootWeb案例——Tlias智能学习辅助系统(3)——登录校验

前一节已经实现了部门管理、员工管理的基本功能。但并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台&#xff0c;这节来实现登录认证。 目录 登录功能登录校验(重点)会话技术会话跟踪方案一 Cookie&#xff08;客户端会话跟踪技术&#xff09;会话跟踪方案二…...

hive和spark-sql中 日期和时间相关函数 测试对比

测试版本&#xff1a; hive 2.3.4 spark 3.1.1 hadoop 2.7.7 1、增加月份 add_months(timestamp date, int months)add_months(timestamp date, bigint months)Return type: timestampusage:add_months(now(),1) 2、增加日期 adddate(timestamp startdate, int days)…...

Cell和RefCell

Cell和RefCell CellRefCellRefCell在运行时记录借用结合Rc和RefCell来拥有多个可变数据所有者引用循环与内存泄漏制造引用循环避免引用循环&#xff1a;将Rc变为Weak创建树形数据结构&#xff1a;带子节点的Node增加从子到父的引用可视化strong_count 和 weak_count 的改变 Rus…...

DaoWiki(基于Django)开发笔记 20231113

DaoWiki&#xff08;基于Django&#xff09;开发笔记 20231113 开发环境 操作系统 windows11python版本 3.12.0django版本 4.2.7 构建python虚拟环境 python -m venv daowiki启动python虚拟环境 cd daowiki\Scripts .\activate安装Django pip install django4.2.7创建项目…...

照片放大软件 Topaz Gigapixel AI mac中文版简介

Topaz Gigapixel AI mac是一款使用人工智能功能扩展图像的桌面应用程序&#xff0c;同时添加自然细节以获得惊人的效果。使用深度学习技术&#xff0c;A.I.Gigapixel™可以放大图像并填写其他调整大小的产品遗漏的细节&#xff0c;使用A.I.Gigapixel™&#xff0c;您可以裁剪照…...

某手游完整性校验分析

前言 只是普通的单机手游&#xff0c;广告比较多&#xff0c;所以分析处理了下&#xff0c;校验流程蛮有意思的&#xff0c;所以就分享出来了 1.重打包崩溃处理 样本进行了加固&#xff0c;对其dump出dex后重打包出现崩溃 ida分析地址发现为jni函数引起 利用Xposed直接替换…...

【ElasticSearch】学习使用DSL和RestClient编写查询语句

文章目录 DSL和RestClient的学习前言1、DSL查询文档1.1 查询分类1.2 全文检索查询1.21 全文检索概述1.2.2 基本使用 1.3 精确查询1.3.1 term查询1.3.2 range查询 1.4 地理坐标查询1.4.1 geo_bounding_box查询1.4.2 geo_distance查询 1.5 复合查询1.5.1 常见相关性算法1.5.2 算分…...

asp.net外卖网站系统VS开发mysql数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net外卖网站系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为mysql&#xff0c;使用c#语…...

2.4.0 Milky Way 强势登场!新功能大爆炸,让你High翻全场!

Yo开发达人们&#xff0c;我们有重磅新功能要给你们放送啦&#xff01; Check it out 数据汇总不再单调&#xff0c;新的聚合函数登场&#xff01; compact_state_agg #1359gauge_agg #1370first #1395last #1413mode #1440increase #1476delta #1395time_delta #1405rate #14…...

C语言----静态链接库和动态链接库

在前面的文章中讲到可执行程序的生成需要经过预处理&#xff0c;编译&#xff0c;汇编和链接四个步骤&#xff0c;链接阶段是链接器将该目标文件与其他目标文件、库文件、启动文件等链接起来生成可执行文件。 需要解读一下库文件&#xff0c;我们可以将库文件等价为压缩包文件&…...

PCA(主成分分析)数据降维技术代码详解

引言 随着大数据时代的到来&#xff0c;我们经常会面临处理高维数据的问题。高维数据不仅增加了计算复杂度&#xff0c;还可能引发“维度灾难”。为了解决这一问题&#xff0c;我们需要对数据进行降维处理&#xff0c;即在不损失太多信息的前提下&#xff0c;将数据从高维空间…...

Git版本控制系统之分支与标签(版本)

目录 一、Git分支&#xff08;Branch&#xff09; 1.1 分支作用 1.2 四种分支管理策略 1.3 使用案例 1.3.1 指令 1.3.2 结合应用场景使用 二、Git标签&#xff08;Tag&#xff09; 2.1 标签作用 2.2 标签规范 2.3 使用案例 2.3.1 指令 2.3.2 使用示例 一、Git分支&…...

JSP运行环境搭建

将安装JSP引擎的计算机称作一个支持JSP的Web服务器。这个服务器负责运行JSP&#xff0c;并将运行结果返回给用户。 JSP的核心内容之一就是编写JSP页面,JSP页面是Web应用程序的重要组成部分之一。一个简单Web应用程序可能只有一个JSP页面,而一个复杂的Web应用程序可能由许多JSP…...

React通过属性 (props) 和状态 (state) 来传递和管理组件的数据

import React, { useState } from react;// 子组件 const ChildComponent (props) > {return (<div><h2>Hello, {props.name}!</h2></div>); }// 父组件 const ParentComponent () > {const [name, setName] useState(John Doe);const handle…...

Web相机和浏览器的二维码扫描方案

Web相机和适用于浏览器的二维码扫描方案 qr-camera 在线体验 | English 功能 支持浏览器扫描二维码支持拍照支持录像功能支持二维码解析和生成 quickstart npm i qr-cameraimport {QRCamera} from qr-camera;function main(){const camera new QRCamera();document.body…...

云端部署ChatGLM-6B

大模型这里更新是挺快的&#xff0c;我参考的视频教程就和我这个稍微有些不一样&#xff0c;这距离教程发布只过去4天而已… 不过基本操作也差不多 AutoDL算力云&#xff1a;https://www.autodl.com/home ChatGLM3&#xff1a;https://github.com/THUDM/ChatGLM3/tree/main Hug…...

Qwen3-14B私有部署镜像:利用MATLAB进行大模型输出数据分析与可视化

Qwen3-14B私有部署镜像&#xff1a;利用MATLAB进行大模型输出数据分析与可视化 1. 科研数据分析的新思路 在科研和工程领域&#xff0c;我们经常需要处理大量文本数据。传统的人工分析方法不仅耗时耗力&#xff0c;而且难以发现深层次的规律。Qwen3-14B作为一款强大的开源大语…...

SDMatte多GPU并行推理配置:提升企业级批量处理吞吐量

SDMatte多GPU并行推理配置&#xff1a;提升企业级批量处理吞吐量 1. 为什么需要多GPU并行推理 当企业需要处理大批量图片时&#xff0c;单张GPU往往难以满足需求。想象一下&#xff0c;你有一家电商公司&#xff0c;每天需要处理上万张商品图片的背景替换。如果只用一张GPU&a…...

#CSDN博客-智能客服RAG实战

基于 Milvus Ollama(BGE-M3) DeepSeek 的智能客服 RAG 实战 一、项目背景 在社保、医保、就业等公共服务领域&#xff0c;每天都有大量群众拨打热线咨询相似问题。传统人工客服成本高、效率低&#xff0c;而基于关键词匹配的机器人又难以理解用户的真实意图。 本项目基于 …...

Adobe-GenP 3.0:二进制智能修补技术破解创意软件授权壁垒

Adobe-GenP 3.0&#xff1a;二进制智能修补技术破解创意软件授权壁垒 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP 3.0作为一款基于AutoIt脚本开发的通…...

Obsidian PDF++:构建PDF与知识网络的无缝连接

Obsidian PDF&#xff1a;构建PDF与知识网络的无缝连接 【免费下载链接】obsidian-pdf-plus PDF: the most Obsidian-native PDF annotation & viewing tool ever. Comes with optional Vim keybindings. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-pdf-plus…...

Win11Debloat:重构Windows 11系统体验的开源优化工具

Win11Debloat&#xff1a;重构Windows 11系统体验的开源优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and cus…...

VirtualRouter:构建企业级无线接入点的零成本解决方案

VirtualRouter&#xff1a;构建企业级无线接入点的零成本解决方案 【免费下载链接】VirtualRouter Wifi Hotspot for Windows computers (Windows 7, 8.x, Server 2012 and newer!) 项目地址: https://gitcode.com/gh_mirrors/vi/VirtualRouter 【痛点场景分析】你的网络…...

第二十五节:Skill的打包、版本控制与社区发布

引言 上一章&#xff0c;我们为Skill精心打造了专业的README文档&#xff0c;这好比为产品准备好了精美的说明书。但要让用户能真正“安装”并使用你的成果&#xff0c;我们还需要完成从本地项目到可分发“产品”的关键转化。本章&#xff0c;我们将聚焦于Skill的打包、版本控制…...

IC版图新手避坑:用Layout XL做Floorplan时,关闭飞线的正确姿势与常见误区

IC版图设计实战&#xff1a;Layout XL飞线管理的艺术与科学 在IC版图设计的世界里&#xff0c;飞线&#xff08;Rubber Band&#xff09;就像一把双刃剑——它既是连接关系的直观体现&#xff0c;也可能成为视觉干扰的源头。特别是当设计规模达到数万甚至数十万门级时&#xff…...

STM32F103C8T6实战:I2C驱动STP23L测距传感器与OLED显示优化

1. 项目背景与硬件选型 第一次接触STM32F103C8T6驱动STP23L测距传感器时&#xff0c;我完全没料到这个蓝色小模块会成为后续多个项目的核心组件。STP23L是一款基于TOF&#xff08;飞行时间&#xff09;原理的激光测距传感器&#xff0c;测量范围0.1-3米&#xff0c;精度可达1m…...