一,前言
起因是因为自己为了做测试写了一篇求助帖,然后最后自己结贴,结贴的实现原理来源于对可变性的理解加深。(顺便吐槽下,现在CSDN还没有针对Rust的代码段格式)
可变性是一个不是借用(&mut
)就是绑定的属性(&mut
)。这意味着,你不能拥有一个一些字段可变而一些字段不可变的struct[结构体]。
struct,是一个自定义数据类型,允许你命名和包装多个相关的值,从而形成一个有意义的组合。
基础类型显然实现不了可变的操作,然而,通过使用Cell<T>
,你可以模拟字段级别的可变性:
struct Ent1{
gl:i32,
sl:i32
}
//不过可以这样
struct Ent1{
name:String,
gl:i32,
sl:i32
}
//像这样是不行了
struct Ent1{
name:String,
mut gl:i32,
mut sl:i32
}
二,实现
以下是通过使用Cell<T>的
代码实现:
use std::cell::Cell;
fn main() {
let ent = Ent::default();
ent.println();
let mut ent = Ent::new("一",5);
let ent2 = Ent::new("二",10);
ent.println();//为了方便输出,实现的方法
println!("{}",ent.compare(&ent2));
ent.add(&ent2);
ent.println();
ent.edit(&ent2);
ent.println();
ent.clear();
ent.println();
}
struct Ent{
name:String,
gl:Cell<i32>,
sl:Cell<i32>
}
impl Ent {
fn default() -> Self {
Ent {
name: "".to_string(),
gl:Cell::new(0),
sl:Cell::new(0),
}
}
fn new(name: &str ,gl: i32) -> Ent {
Ent {
name: name.to_string(),
gl:Cell::new(gl),
sl:Cell::new(0),
}
}
fn println(&self) {
println!("name:{} , gl:{} , sl:{}",self.name,self.gl.get(),self.sl.get());
}
fn clear(&mut self) {
self.name = "".to_string();
self.gl.set(0);
self.sl.set(0);
}
fn add(&mut self, other: & Ent) {
self.gl.set(self.gl.get() + other.gl.get());
self.sl.set(self.sl.get() + other.sl.get());
}
fn edit(&mut self, other: & Ent) {
self.gl.set(other.gl.get());
self.sl.set(other.sl.get());
}
fn compare(&self, other: &Ent) -> bool {
self.gl > other.gl && self.sl > other.sl
}
}
console:
name: , gl:0 , sl:0
name:一 , gl:5 , sl:0
false
name:一 , gl:15 , sl:0
name:一 , gl:10 , sl:0
name: , gl:0 , sl:0
三,unsafe实现
可以通过 unsafe 关键字来切换到不安全 Rust,接着可以开启一个新的存放不安全代码的块。这里有四类可以在不安全 Rust 中进行而不能用于安全 Rust 的操作,它们是:
解引用裸指针
调用不安全的函数或方法
访问或修改可变静态变量
实现不安全 trait
fn main() {
let mut ent = Ent::new("", 0,2);
let mut ent2 = Ent::new("", 1,2);
ent.add(&ent2);
println!("{} , {}",&ent.gl,&ent.sl);//1 , 4
}
struct Ent{
name:String,
gl:i32,
sl:i32
}
impl Ent {
fn new(name: &str ,gl: i32,sl: i32) -> Ent {
Ent {
name: name.to_string(),
gl,
sl,
}
}
fn add(&mut self, other: & Ent) {
unsafe{
self.gl += other.gl;
self.sl += other.sl;
}
}
}
、