里面有,你没有仔细看。比如这个:
// 定义一个实现了`Deref<T> trait`, `AsRef<T> trait`, `Borrow<T> trait`
// 的自定义类型。
mod number {
use std::{borrow::Borrow, cmp::Ordering, hash::{Hash, Hasher}, ops::Deref};
// 【源·类型】作为【容器·类型】;【目标·类型】作为【内部·数据类型】
#[derive(Copy, Clone, Default)]
pub struct SafeNumber(pub i32);
impl SafeNumber { // 【源·类型】提供【目标·类型】不具备的额外功能或语义
pub fn add_10(&mut self) {
self.0 += 10;
}
}
impl Deref for SafeNumber { // `SafeNumber`成为了`i32`的智能指针
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<i32> for SafeNumber {
fn as_ref(&self) -> &i32 {
&self.0
}
}
// 给`Eq trait`, `Hash trait`与`Ord trait`提供与【目标·类型】行为一致的
// 实现是正确实现`Borrow trait`的前提条件。
impl Hash for SafeNumber {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
impl PartialEq for SafeNumber {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl Eq for SafeNumber {}
impl PartialOrd for SafeNumber {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for SafeNumber {
fn cmp(&self, other: &Self) -> Ordering {
self.0.cmp(&other.0)
}
}
impl Borrow<i32> for SafeNumber {
fn borrow(&self) -> &i32 {
&self.0
}
}
}
use std::borrow::Borrow;
use number::SafeNumber;
fn main() {
let mut ms1 = SafeNumber(15,);
let ms2 = SafeNumber(15,);
let s = 15;
output1(&ms1); // 从`&SafeNumber -> &i32`类型转换
output2(ms1.clone()); // 从`SafeNumber -> AsRef<i32> -> &i32`类型转换
assert!(equals(ms1.clone(), s)); // 从`&SafeNumber -> Borrow<i32> -> &i32`类型转换
assert_eq!( // Borrow<T> 会要求相同的【判等·标准】。
<SafeNumber as Borrow<i32>>::borrow(&ms1) == <SafeNumber as Borrow<i32>>::borrow(&ms2),
ms1 == ms2
);
ms1.add_10();
// 从`&SafeNumber -> &i32`类型转换。
// 零编码成本·就获得了·函数重载的(部分)效果。
// 只要是`i32`的【智能指针】包装类型都可以作为该函数的实参。
fn output1(src: &i32) {
println!("{src}");
}
// 从`SafeNumber -> &i32`类型转换,有【泛型·代码】成本。
// 借助【泛型·编程】与`AsRef::as_ref()`成员方法调用·就获得了·函数重载的(部分)效果。
// 只要是实现了`AsRef<i32> tait`的包装类型都可以作为该函数的实参。
fn output2<T: AsRef<i32>>(src: T) {
let src = src.as_ref();
println!("{src}");
}
// 从`SafeNumber -> &i32`类型转换,有【泛型·代码】成本。
// 借助【泛型·编程】与`Borrow::borrow()`成员方法调用·就获得了·函数重载的(部分)效果。
// 除了实现`Borrow<str> trait`,【源·类型】还需要提供与【目标·类型`i32`】行为一致的
// `Eq`, `Ord`与`Hash trait`实现。
fn equals<T1, T2>(s1: T1, s2: T2) -> bool
where T1: Borrow<i32>,
T2: Borrow<i32> {
s1.borrow() == s2.borrow()
}
}
【 在 munaiyi 的大作中提到: 】
: 能举一些代码例子会好了,如果能结合实际场景就更好了
: 干巴巴一些总结,没味道
:
--
FROM 117.147.21.*