You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何值相同的&str、String、&String、&i32实例及引用比较结果均相等?

Rust中不同类型实例相等性的疑问解答

首先先看你提供的代码示例:

fn main() { 
    let v1 = 5; 
    let v2 = 5; 
    let mut s = String::new(); 
    s.push_str("a"); 
    println!("{}", "a" == "a"); 
    println!("{}", String::from("a") == String::from("a")); 
    println!("{}", String::from("a") == s); 
    println!("{}", &String::from("a") == &s); 
    println!("{}", &v1 == &v2); 
}

你的疑问非常切中要害——明明这些实例的内存地址不同,为什么==比较结果都是相等?核心原因在于:Rust的==运算符不是直接比较内存地址,而是调用了类型实现的PartialEq trait,而绝大多数标准库类型都是按「值语义」来实现这个trait的。

咱们分场景具体解释:

1. &str 之间的比较

字符串字面量"a"属于&str类型,它的PartialEq实现逻辑是比较指向的字符串内容,而非指针本身的地址。哪怕两个&str来自不同的内存区域(比如一个是编译期字面量,一个是从String切片而来),只要字节内容完全一致,比较结果就是true。

2. String 实例之间的比较

String结构体本身包含三个字段:指向堆内存的指针、字符串长度、容量,但它的PartialEq实现会直接跳过这些结构体字段,转而比较堆内存里的实际字符串内容。所以哪怕两个String实例在堆上的内存地址完全不同,只要存储的字符一样,==就会返回true。

3. String 和 &str 的跨类型比较

这得益于Rust的**解引用强制转换(deref coercion)**机制:当你用==比较String和&str时,String会被自动解引用为&str,最终还是回到了字符串内容的比较,自然结果相等。

4. &String 引用之间的比较

&String的PartialEq实现会先把引用解引用为&str,再比较内容。换句话说,它比较的是引用指向的String实例的实际值,而非两个引用本身的内存地址。所以哪怕两个&String指向不同的String实例,只要实例内容相同,比较结果就是true。

5. &i32 引用之间的比较

像整数这种基础Copy类型,&i32的PartialEq实现逻辑是比较引用指向的整数值,而非指针地址。毕竟对于简单数值类型,比较值本身才是符合直觉的行为,Rust默认就这么设计了。

额外补充:如果想比较内存地址怎么办?

如果确实需要判断两个实例的内存地址是否相同,可以使用std::ptr::eq函数,它会直接比较指针的地址:

let s1 = String::from("a");
let s2 = String::from("a");
println!("{}", std::ptr::eq(&s1, &s2)); // 输出false,两个String实例地址不同
println!("{}", std::ptr::eq(s1.as_str(), s2.as_str())); // 输出false,动态分配的String切片地址不同

内容的提问来源于stack exchange,提问作者Wynell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:59:06