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

从T类型变量创造一个新的T类型变量就是玩转Rust高级应用. ToOwned trait 给出的是一种更“泛化”的Clone 的特性,Clone一般

标准库简介

除了前面介绍过的容器、迭代器之外,标准库还提供了一系列有用的类型、函数、 trait 等。本章挑选其中比较常见的一部分简单介绍。

类型转换

Rust 给我们提供了一个关键字as 用于基本类型的转换。但是除了基本类型之外,还有 更多的自定义类型,它们之间也经常需要做类型转换。为此, Rust 标准库给我们提供了一系 列 的trait 来辅助抽象。

AsRef/AsMut

AsRef 这个trait 代表的意思是,这个类型可以通过调用as_ref方法,得到另外一个 类型的共享引用。它的定义如下:

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

同 理 ,ASMut 有 一 个 as_mut方法,可以得到另外一个类型的可读写引用:

pub trait ASMut < T: ?Sized > {fn as_mut( & mut self) - >&mut T;}

比如说,标准库里面的String类型,就针对好几个类型参数实现了AsRef trait:

impl AsRef < str >for String impl AsRef < [u8] >for String impl AsRef < 0sStr >for String impl AsRef < Path >for String

AsRef 这样的trait 很适合用在泛型代码中,为一系列类型做统一抽象。比如,我们可 以写一个泛型函数,它接受各种类型,只要可以被转换为&[u8] 即可:

fn iter_bytes < T: AsRef < [u8] >> (arg: T) {for i in arg.as_ref() {println ! ("{}", i);}}fn main() {let s: String = String: :from("this is a string");let v: Vec < u8 >= vec ! [1, 2, 3];let c: &str = "hello";}

相当于函数重载。只不过基于泛型实现的重载,一定需要重载的参数类型满足某种共同的约束 iter_bytes(s);

{
iter_bytes(V);
iter_bytes(c);
}

Borrow/BorrowMut

Borrow 这个trait 设计得与AsRef 非常像。它是这样定义的:

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

可以说,除了名字之外,它和AsRef 长得一模一样。但它们的设计意图不同。比如, 针对String 类型,它只实现了一个Borrow:

impl Borrow<str>for String

这是因为这个trait 一般被用于实现某些重要的数据结构,比如HashMap:

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

和 BTreeMap:

impl BTreeMap {
pub fn get < Q: ?Sized > ( & self, key: &Q) - >Option < &V > where K: Borrow < Q > ,Q: Ord {}}

所以,它要求borrow() 方法返回的类型,必须和原来的类型具备同样的hash值,以及排序。这是一个约定,如果实现Borrow trait的时候违反了这个约定,那么把这个类型放 到 HashMap 或者BTreeMap 里面的时候就可能出现问题。


From/Into

AsRef/Borrow做的类型转换都是从一种引用&T 到另一种引用&U的转换。而From/Into 做的则是从任意类型T 到 U 的类型转换:

pub trait From < T > {fn from(T) - >Self;}pub trait Into < T > {fn into(self) - >T;}

显然,From 和 Into 是互逆的一组转换。如果T 实现了From, 那 么U理应实现 Into 。 因此,标准库里面提供了这样一个实现:

impl < T,
U > Into < U >for T where U: From < T > {fn into(self) - >U {U: :from(self)}}

用自然语言描述,意思就是:如果存在U:From, 则实现T:Into

正是因为标准库中已经有了这样一个默认实现,我们在需要给两个类型实现类型转换的 trait的时候,写一个From 就够了,Into 不需要自己手写。

比如,标准库里面已经给我们提供了这样的转换:

impl<a>From<&a str>for String

这意味着&str 类型可以转换为String 类型。我们有两种调用方式: 一种是通过 String::from(&str) 来使用,一种是通过&str::into() 来使用。它们的意思一样:

fn main() {
let s: &'static str ="hello";
let str1:String =s.into();
let str2:String =String::from(s);
}

另外,由于这几个trait很常用,因此Rust已经将它们加入到prelude中。在使用的时 候我们不需要写use std::convert::From;这样的语句了,包括AsRef、ASMut、Into、From、ToOwned 等。具体可以参见libstd/prelude/v1.rs源代码的内容。

标准库中还有一组对应的TryFrom/TryInto 两个trait, 它们是为了处理那种类型转 换过程中可能发生转换错误的情况。因此,它们的方法的返回类型是Result类型。


ToOwned

ToOwned trait 提供的是一种更“泛化”的Clone 的功能。Clone 一般是从&T 类型变 量创造一个新的T 类型变量,而ToOwned 一般是从一个&T 类型变量创造一个新的U类型 变 量 。

在标准库中,ToOwned 有一个默认实现,即调用clone 方法:

impl < T > ToOwnedfor T where T: Clone {type Owned = T;fn to_owned( & self) - >T {self.clone()fn clone_into( & self, target: &mut T) {target.clone_from(self);}}}

但是,它还对一些特殊类型实现了这个trait 。比如:

impl < T: Clone > ToOwnedfor [T] {type Owned = Vec < T > ;}impl ToOwnedfor str {type Owned = String;}

而且,很有用的类型Cow 也是基于ToOwned 实现的:

pub enum Cow < 'a,B>whereB:'a + ToOwned + ?Sized,{Borrowed( & 'a B),Owned(<B as ToOwned>::Owned),}// ToString trait提供了其他类型转换为String 类型的能力。pub trait ToString{fn to_string(&self)->String;}

一般情况下,我们不需要自己为自定义类型实现ToString trait。因为标准库中已经提供 了 一 个 默 认 实 现 :

impl < T: fmt: :Display + ?Sized > ToStringfor T {# [inline]default fn to_string( & self) - >String {use core: :fmt: :Write;let mut buf = String: :new();buf.write_fmt(format_args ! ("{}", self)).expect("a Display implementation return an error     unexpectedly");buf.shrink_to_fit();buf}}

这意味着,任何一个实现了Display trait 的类型,都自动实现了ToString trait。而 Display trait 是可以自动derive 的,我们只需要为类型添加一个attribute 即可。

FromStr则提供了从字符串切片&str 向其他类型转换的能力。

pub trait FromStr {
type Err;
fn from_str(s: &str) - >Result < Self,
Self: :Err > ;
}

因为这个转换过程可能出错,所以from_str 方法的返回类型被设计为Result。正是因为有了这个trait, 所 以str类型才有了一个成员方法parse:

pub fn parse<F:FromStr>(&self)->Result<F,F::Err>{}

所以我们可以写下面这样非常清晰直白的代码:

let four ="4".parse::<u32>();assert_eq!(Ok(4),four);
http://www.jsqmd.com/news/374186/

相关文章:

  • 解决LLM推理“脑裂”难题:Kubernetes LeaderWorkerSet(LWS)组件在大模型推理部署中的应用
  • 盘点2026年郑州荷花国际月子中心,服务性价比高值得选 - 工业推荐榜
  • 基于深度学习的遥感地面物体检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Django+web+训练代码+数据集)
  • 深度解析:Binpack调度策略在智算场景中的优势与作用
  • 2026年全国别墅电梯品牌哪家有实力?靠谱耐用 适配高端住宅与旧楼加装 多场景个性化需求 - 深度智识库
  • 2026年股票配资平台选择标准:安全、正规、实盘三大核心 - 资讯焦点
  • 总结浙江比较好的女士西装专业公司,哪家服务更好 - 工业品网
  • 宏邦机械转台费用多少钱,性价比品牌排名 - 工业品牌热点
  • 续传文件夹在JSP中怎么操作?
  • 评价高的装修装饰服务公司,上海地区选购时要注意什么 - mypinpai
  • 盒马鲜生卡回收攻略,秒变现金! - 团团收购物卡回收
  • 2026年高口碑股票配资平台有哪些?安全实盘用户推荐榜 - 资讯焦点
  • JSP如何实现文件夹的分片上传功能?
  • 2026年衡水口碑好的AI搜索推广公司排名,靠谱机构哪家值得选 - myqiye
  • 探讨福斯曼与同行业优势,售后保障及产品耐用性靠谱吗 - 工业品网
  • 2026年实盘股票配资平台排名深度解析:安全合规与实力并重 - 资讯焦点
  • ServiceNow 国产替代深度分析:从功能覆盖到价值落地
  • 2026年CE认证靠谱服务商排名,说说服务不错的CE认证机构哪家性价比高 - 工业设备
  • 2026年股票配资安全操作指南:如何选择100%实盘的正规平台 - 资讯焦点
  • 配电柜厂家破局指南:5P全场景方法论如何解决行业四大痛点? - 速递信息
  • 2026年股票配资平台服务评测:安全、正规、实盘,谁更胜一筹? - 资讯焦点
  • 构建AI智能体,勿忘基本安全问题
  • 说说洛阳汽车贴膜品牌,洛阳鑫瑞威固7V旗舰店靠谱吗 - 工业品牌热点
  • 优雅终结启动顺序噩梦:ObjectProvider —— Spring 4.3 开始引入
  • 2026年股票配资平台哪家靠谱?安全正规实盘公司盘点 - 资讯焦点
  • 2026年制造业海外社媒代运营服务商推荐(2月更新):Facebook、LinkedIn、TikTok、Google、INS、独立站等全平台覆盖 - 品牌2025
  • 负环、差分约束与2-SAT
  • 2026年国内股票配资平台深度评测:哪些公司是真正的实盘交易? - 资讯焦点
  • 股票配资平台安全吗?2026年最新实盘正规平台评测报告 - 资讯焦点
  • 【南京】个人心理咨询室推荐:五大专业机构横向测评 - 野榜数据排行