Rust - 强制修改私有变量

有一个场景,你导了一个奇怪的库,其中有一个结构体私有字段你要修改已达到奇怪的目的,但是他是私有的嘛,你不能直接改,怎么办呢?

Unsafe大法

源代码

mod pri {
    pub struct MyPrivateStruct {
        name: String,
        age: u32,
    }

    impl MyPrivateStruct {
        pub fn new(name: String, age: u32) -> Self {
            MyPrivateStruct {
                name,
                age,
            }
        }

        pub fn display(&self) {
            println!("Name: {}, Age: {}", self.name, self.age);
        }
    }
}


#[tokio::main]
async fn main() {
    let st = pri::MyPrivateStruct::new("John".to_string(), 25);
    // println!("Name: {}, Age: {}", st.name, st.age); error
    st.display();
}

这里有一个MyPrivateStruct 你没办法对他里面的字段进行修改,因为私有。

解决方法

mod pri {
    pub struct MyPrivateStruct {
        name: String,
        age: u32,
    }

    impl MyPrivateStruct {
        pub fn new(name: String, age: u32) -> Self {
            MyPrivateStruct {
                name,
                age,
            }
        }

        pub fn display(&self) {
            println!("Name: {}, Age: {}", self.name, self.age);
        }
    }
}

pub struct MyCopyPrivateStruct {
    pub name: String,
    pub age: u32,
}

#[tokio::main]
async fn main() {
    let mut st = pri::MyPrivateStruct::new("John".to_string(), 25);
    // println!("Name: {}, Age: {}", st.name, st.age); error
    st.display();
    unsafe {
        let st_ptr = &mut st as *mut pri::MyPrivateStruct;
        let mycpst = mem::transmute::<*mut pri::MyPrivateStruct, *mut MyCopyPrivateStruct>(st_ptr);
        (*mycpst).name = "Doe".to_string();
        (*mycpst).age = 30;
    }
    st.display();
}

并不能保证内存结构一致哦,这个是一个UB!

重写依赖(Patch)

如果你拥有你要修改的那个玩意的源代码,你可以看看这篇文章