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

rust - 理解borrow trait

简介

borrow trait 是处理借用(即其它语言中的引用)的 trait,变量的所有权不会转移.泛型定义如下:

pub trait Borrow<Borrowed: ?Sized> {/// Immutably borrows from an owned value.fn borrow(&self) -> &Borrowed;
}

其中包含一个 borrow(&self)的方法,将变量的类型 T 转换为 &Borrowed 类型.

默认实现

rust 提供了类型 T 的默认实现,如下:

impl<T: ?Sized> Borrow<T> for T {fn borrow(&self) -> &T {self}
}impl<T: ?Sized> Borrow<T> for &T {fn borrow(&self) -> &T {&**self}
}impl<T: ?Sized> Borrow<T> for &mut T {fn borrow(&self) -> &T {&**self}
}

这里创建一个自定义类型来说明 borrow 的默认实现,如下

    #[test]fn test_default_borrow() {struct MyType;let my_type = MyType;let _: &MyType = my_type.borrow();let _: &MyType = (&my_type).borrow();let my_type = &MyType;let _: &MyType = my_type.borrow();let _: &MyType = (*my_type).borrow();let my_type = &mut MyType;let _: &MyType = my_type.borrow();let _: &MyType = (*my_type).borrow();}

自定义 borrow trait

String 类型就实现了自己的 borrow trait,如下:

impl Borrow<str> for String {#[inline]fn borrow(&self) -> &str {&self[..]}
}

即将 String 类型转换为了 &str 类型.

可以自己对类型实现 Borrow trait,如下:

#[allow(dead_code)]
struct Person {name: String,age: u8,
}impl Borrow<str> for Person {fn borrow(&self) -> &str {self.name.as_str()}
}

实现Borrow的一个要求是,借用值的HashEqOrd与拥有值的HashEqOrd相等。这里可以解释为,如果两个用户 Person 的借用值 name 相同,则认为是同一个人.

使用场景

1. 对函数参数进行类型扩展

    #[test]fn test_origin_check() {fn origin_check(s: &String) {assert_eq!("Hello", s);}let s = "Hello".to_string();origin_check(&s);}

例如,上面的函数origin_check接受 String 类型的参数,但是如果想复用这个函数,需要将其它类型的参数也传给origin_check函数该怎么实现呢?

先修改成第一个版本, 添加s.borrow(), 如下

    #[test]fn test_origin_check_1() {fn origin_check(s: &String) {let borrowed: &str = s.borrow();assert_eq!("Hello", borrowed);}let s = "Hello".to_string();origin_check(&s);}

这样只要确保类型 s,都实现了 borrow()方法,且返回值的类型都为 &str就可行了.

再修改成第二个版本, 这样就可以将任何实现了Borrow<str>类型的变量作为参数传递给函数check,如下:

    fn check<K>(s: K)whereK: Borrow<str>,{let borrowed: &str = s.borrow();assert_eq!("Hello", borrowed);}#[test]fn test_borrow_as_param() {// 支持 String 类型,因为 String 实现了 Borrow trait,可以转换为 &strlet s = "Hello".to_string();check(s);// 支持 &str 类型,因为 rust 实现了类型 T 的默认 borrow 实现, 转换为 &str 类型let s = "Hello";check(s);// 支持 Person 类型,因为 Person 实现了 Borrow trait, 可以转换为用户名属性的 &str 类型let s = Person { name: "Hello".to_string(), age: 18 };check(s);}
http://www.lryc.cn/news/209416.html

相关文章:

  • review-java-basis
  • Go 语言访问 Redis 笔记
  • 【MySQL数据库重点】第二节:MySQL基础知识(基本操作)
  • 计算机网络--第一次作业
  • 网络协议--TCP的成块数据流
  • 鼎鑫鸿鄴引入“能源互联网+”理念 打造共赢
  • Qt下实现支持多线程的单例模式
  • 基于Java的宠物商店管理系统设计与实现(源码+lw+部署文档+讲解等)
  • ArcGIS中批量mxd高版本转低版本
  • 三篇论文:速览GPT在网络安全最新论文中的应用案例
  • 美术如何创建 skybox 贴图资源?
  • 【Linux 用户,用户组管理】
  • VS2022 C# 读取 excel 2023年
  • C# | Chaikin算法 —— 计算折线对应的平滑曲线坐标点
  • day44
  • python常用操作汇总
  • 赴日IT培训 日本IT行业为啥吃香?
  • 2016年亚太杯APMCM数学建模大赛A题基于光学信息数据的温度及关键元素含量预测求解全过程文档及程序
  • 一文讲明:企业知识库的作用和搭建方法
  • 技术的新浪潮:从SOCKS5代理到跨界电商的未来
  • Android intent的一些小使用
  • Android 关闭 SELinux 释放权限限制
  • 国际腾讯云自主拼装直播 URL教程!!!
  • AQS 为什么要使用双向链表?
  • Golang 自定义函数库(个人笔记)
  • openlayers 地图组件封装
  • 【算法设计与分析】—— 分治算法
  • Unable to find GatewayFilterFactory with name TokenRelay
  • 竞赛 深度学习大数据物流平台 python
  • git基础及原理相关解析