Rust那些事之Borrow VS AsRef​


最近看到两个trait长得挺像,带着疑惑前来学习一下。

Borrow VS AsRef

Borrow与AsRef是Rust中非常相似的两个trait,分别是:

pub trait Borrow<Borrowed: ?Sized> {
    fn borrow(&self) -> &Borrowed;
}

pub trait AsRef<T: ?Sized> {
    fn as_ref(&self) -> &T;
}

可以看到这两个从接口层面是一样的。

使用方式如下:

let s = String::from("Hello World");
let s_ref: &str = s.borrow(); // using Borrow
let s_ref: &str = s.as_ref(); // using AsRef

那么问题来的,什么时候使用Borrow,什么时候使用AsRef呢?

1.trait一致性

  • Borrow also requires that Hash, Eq and Ord for a borrowed value are equivalent to those of the owned value. For this reason, if you want to borrow only a single field of a struct you can implement AsRef, but not Borrow.

Borrow 还要求对于借用值的HashEqOrd 与拥有值相等。因此,如果你只想借用结构体的单个字段,你可以实现 AsRef,但不能实现 Borrow

如果类型T1实现了Borrow<T2>,在为T1实现一些特殊的trait(例如:Eq、Ord、Hash)时,其行为应该与T2有相同的行为。

例如:标准库 HashMap 对 get() 和 get_mut() 方法使用了Borrow 特征。K是HashMap的key,而get接收的是k类型是&Q

例如:HashMap<String, xx>,K就是String,Q就是str,这允许我们可以传递任何可以作为 K 借用的类型 Q。通过额外要求 Q: Hash + Eq,它表明要求 K 和 Q 具有产生相同结果的 Hash 和 Eq  trait的实现。

impl<K, V> HashMap<K, V> {
    pub fn get<Q>(&self, k: &Q) -> Option<&V>
    where
        K: Borrow<Q>,
        Q: Hash + Eq + ?Sized
    {
        // ...
    }
}

https://doc.rust-lang.org/std/borrow/trait.Borrow.html

2.默认实现

  • Unlike AsRef, Borrow has a blanket impl for any T, and can be used to accept either a reference or a value. (See also note on AsRef’s reflexibility below.)

AsRef 不同,Borrow 为任何 T 都有一个默认实现,并且可以用来接受引用或值。

例如:使用Borrow下面代码可以正常工作。

use std::borrow::Borrow;

fn print_value<T: Borrow<i32>>(value: T) {
    println!("Value is: {}", value.borrow());
}

fn main() {
    let number = 42;
    print_value(&number); 
    print_value(number); 
}

而如果使用AsRef,则不可以,报错:

the trait `std::convert::AsRef<i32>` is not implemented for `{integer}`

示例:

fn print_value<T: AsRef<i32>>(value: T) {
    println!("Value is: {}", value.as_ref());
}

fn main() {
    let number = 42;
    print_value(&number); 
    print_value(number); 
}

https://doc.rust-lang.org/std/convert/trait.AsRef.html#relation-to-borrow


往期回顾:

我的春招求职面经

热度更新,手把手实现工业级线程池

dca4e61e234393d2ad269b1af4544d3b.jpeg

cfd7f542d193e5163d3f5853b43e97d5.jpeg

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

threejs 组-层级模型 | 本地坐标和世界坐标 | 局部坐标系和世界坐标系 | 本地矩阵.materix和世界矩阵.matrixWorld

文章目录 组- THREE.Group递归遍历模型树结构object3D.traverse()object3D.add (object.Object3D..) 添加对象 和 object3D.remove(object.Object3D..) 移除对象 局部坐标系和世界坐标系辅助坐标器 AxesHelper 本地坐标和世界坐标 - 基于世界坐标系的位置本地坐标与世界坐标的理…

常用的深度学习自动标注软件

0. 简介 自动标注软件是一个非常节省人力资源的操作&#xff0c;而随着深度学习的发展&#xff0c;这些自动化标定软件也越来越多。本文章将会着重介绍其中比较经典的自动标注软件 1. AutoLabelImg AutoLabelImg 除了labelimg的初始功能外&#xff0c;额外包含十多种辅助标注…

机器人码垛机:科技创新推动物流行业飞跃发展

在数字化、智能化浪潮的推动下&#xff0c;机器人技术已成为推动各行各业转型升级的重要力量。特别是在物流行业&#xff0c;机器人码垛机的应用正逐渐普及&#xff0c;以其高效、精准、节省人力的特点&#xff0c;助力物流行业实现跨越式发展。星派将介绍机器人码垛机如何助力…

nacos分布式程序开发实例

1.通过windows docker desktop 完成 nacos 的安装/启动/配置 &#xff08;1&#xff09;先安装docker desktop docker-toolbox-windows-docker-for-windows-stable安装包下载_开源镜像站-阿里云 &#xff08;2&#xff09;配置docker 国内镜像源 Docker 镜像加速 | 菜鸟教程…

C++ list链表模拟实现

目录 前言&#xff1a; 模拟实现&#xff1a; 迭代器的实现&#xff1a; list类功能函数实现&#xff1a; 初始化成空函数&#xff08;empty_init&#xff09;&#xff1a; 构造函数&#xff1a; 拷贝构造函数&#xff1a; 尾插&#xff08;push_back&#xff09;: 插入…

【触想智能】工业一体机和普通电脑的区别是什么?

工业一体机和普通电脑的区别是什么&#xff0c;工业一体机可以当普通电脑一样使用吗? 要想了解工业一体机和普通电脑的区别是什么?我们首先来看看工业一体机是什么&#xff0c;它跟普通电脑有哪些相似的地方?下面小编就为大家来详细介绍一下。 在工作原理上&#xff0c;工业…

GFS分布式 文件系统

一、GFS的概念 文件存储分为nfs、lvm、raid 对象存储分为GFS、CEPH、fastDFS&#xff08;分布式文件存储&#xff09;NAS OSS S3 switch OSS 属于阿里云 通过URL 链接 S3属于亚马逊通过URL链接 1.1 GFS简介 开源的分布式文件系统&#xff0c;由存储服务器、客户端…

Pillow教程11:九宫格切图的实现方法(安排!!!)

---------------Pillow教程集合--------------- Python项目18&#xff1a;使用Pillow模块&#xff0c;随机生成4位数的图片验证码 Python教程93&#xff1a;初识Pillow模块&#xff08;创建Image对象查看属性图片的保存与缩放&#xff09; Pillow教程02&#xff1a;图片的裁…

xv6源码分析 003

xv6源码分析 003 在开始今晚的内容之前我先纠正以下昨天的一个错误 struct cmd {int type; };代表的是在sh.c开头就定义的宏常量&#xff0c;系统调用号是通过汇编代码来传入的。修改之后的内容如下&#xff1a; 好啦&#xff0c;我们继续昨晚的内容吧。 在sh.c 的 main函数中…

大屏可视化展示平台解决方案(word原件获取)

1.系统概述 1.1.需求分析 1.2.重难点分析 1.3.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 2.3.接口及要求 3.系统功能设计 3.1.功能清单列表 3.2.数据源管理 3.3.数据集管理 3.4.视图管理 3.5.仪表盘管理 3.6.移动端设计 3.1.系统权限设计 3.2.数据查询过程设…

如何使用vscode启动Flask并实现无公网IP远程访问内网服务

文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask&#xff0c;以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架&#xff0c;采用Python编程语…

linux网络服务学习(5):iscsi

1.什么是iscsi 1.1 scsi SCSI是一种I/O技术&#xff0c;规范了一种并行的I/O总线和相关协议&#xff08;scsi协议&#xff09;。 SCSI总线通过SCSI控制器&#xff08;target&#xff09;来和硬盘之类的设备&#xff08;scsi设备&#xff09;进行通信&#xff0c;访问的客户端…

图形学物体拾取:CPU VS GPU

一、CPU – raycaster 射线包围盒是一种常用的方法&#xff0c;在 CPU 中进行拾取&#xff0c;性能较好&#xff0c;但是精度较差。当拾取频率不高时&#xff0c;可以考虑使用像素级精度的帧缓冲拾取Framebuffer Picker.射线投射涉及将射线投射到场景中并检查对象和射线之间的…

K8s技术全景:架构、应用与优化

一、介绍 Kubernetes的历史和演进 Kubernetes&#xff08;简称K8s&#xff09;是一个开源的容器编排系统&#xff0c;用于自动化应用程序的部署、扩展和管理。它最初是由Google内部的Borg系统启发并设计的&#xff0c;于2014年作为开源项目首次亮相。 初始阶段 Kubernetes的诞生…

网站想使用https安全协议,必须要安装ssl证书吗?

ssl证书作为保护网站数据传输安全的重要工具&#xff0c;被广泛应用于网站的安全加密通信中。很多人在初次接触ssl证书时&#xff0c;有一个常见的疑问&#xff1a;网站使用https协议必须要ssl证书吗&#xff1f; 答案是肯定的。   HTTPS是一种通过计算机网络进行安全通信的…

计算机网络 网络命令的使用

一、实验内容 1.PING网络命令的实验 ping 127.0.0.1(内部回环测试)ping 本主机的IP地址ping 默认网关地址ping远端目的地的IP地址ping localhostping域名 2.其他网络命令实验 命令用途ipconfig/all 显示当前系统网络配置&#xff0c;包括IP地址、子网掩码、默认网关等trace…

Unity MySql安装部署与Unity连接

1.前言 最近项目用到MySql&#xff0c;记录一下安装部署过程。 数据量过大或者需要管理用户数据的时候用mysql的话数据结构比较清晰明了&#xff0c;便于管理。 2.安装MySql Unity版本&#xff1a;2019.4.16 MySql版本&#xff1a;8.2.0 下载地址&#xff1a;MySql 下载…

LLM - 大语言模型(LLM) 的 应用技术

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/137503579 大语言模型(LLM) 的应用技术范围非常广泛,即: LangChain:开发框架,专为大型语言模型设计,以提高开发人工智能应用的效率,允许开发者将语言模…

Day17_学点JavaEE_转发、重定向、Get、POST、乱码问题总结

1 转发 转发&#xff1a;一般查询了数据之后&#xff0c;转发到一个jsp页面进行展示 req.setAttribute("list", list); req.getRequestDispatcher("student_list.jsp").forward(req, resp);2 重定向 重定向&#xff1a;一般添加、删除、修改之后重定向到…

整理的微信小程序日历(单选/多选/筛选)

一、日历横向多选&#xff0c;支持单日、双日、三日、工作日等选择 效果图 wxml文件 <view class"calendar"><view class"section"><view class"title flex-box"><button bindtap"past">上一页</button&…