MST

星途 面试题库

面试题:Rust复杂数据结构的拷贝测试

假设有一个包含嵌套Vec和自定义结构体的复杂数据结构,例如`struct Outer { inner_vec: Vec<Inner>, data: i32 }`,其中`struct Inner { sub_data: String }`。阐述如何对这样的复杂结构进行浅拷贝和深拷贝的测试,以及在测试过程中可能遇到的陷阱和解决方案。
48.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

浅拷贝测试

  1. 实现 Clone 特质:为 InnerOuter 结构体实现 Clone 特质,使它们默认实现浅拷贝。
    #[derive(Clone)]
    struct Inner {
        sub_data: String,
    }
    
    #[derive(Clone)]
    struct Outer {
        inner_vec: Vec<Inner>,
        data: i32,
    }
    
  2. 编写测试:在测试函数中,创建一个 Outer 实例,进行克隆,并检查克隆后的实例和原实例的内存地址。
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn test_shallow_clone() {
            let original = Outer {
                inner_vec: vec![Inner { sub_data: "test".to_string() }],
                data: 42,
            };
            let cloned = original.clone();
            assert_eq!(original.data, cloned.data);
            assert_eq!(original.inner_vec.len(), cloned.inner_vec.len());
            // 浅拷贝,内部字符串的指针相同
            assert!(std::ptr::eq(
                original.inner_vec[0].sub_data.as_ptr(),
                cloned.inner_vec[0].sub_data.as_ptr()
            ));
        }
    }
    

深拷贝测试

  1. 实现 Clone 特质(深拷贝):手动实现 Clone 特质来进行深拷贝,对于 Inner 结构体,需要对 sub_data 进行深拷贝。
    struct Inner {
        sub_data: String,
    }
    
    impl Clone for Inner {
        fn clone(&self) -> Inner {
            Inner {
                sub_data: self.sub_data.clone(),
            }
        }
    }
    
    struct Outer {
        inner_vec: Vec<Inner>,
        data: i32,
    }
    
    impl Clone for Outer {
        fn clone(&self) -> Outer {
            Outer {
                inner_vec: self.inner_vec.clone(),
                data: self.data,
            }
        }
    }
    
  2. 编写测试:同样创建一个 Outer 实例,进行克隆,并检查克隆后的实例和原实例的内存地址。
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn test_deep_clone() {
            let original = Outer {
                inner_vec: vec![Inner { sub_data: "test".to_string() }],
                data: 42,
            };
            let cloned = original.clone();
            assert_eq!(original.data, cloned.data);
            assert_eq!(original.inner_vec.len(), cloned.inner_vec.len());
            // 深拷贝,内部字符串的指针不同
            assert!(!std::ptr::eq(
                original.inner_vec[0].sub_data.as_ptr(),
                cloned.inner_vec[0].sub_data.as_ptr()
            ));
        }
    }
    

可能遇到的陷阱及解决方案

  1. 默认浅拷贝问题:如果只依赖 #[derive(Clone)],可能得到浅拷贝,导致修改克隆实例的内部数据影响原实例。解决方案是手动实现 Clone 特质进行深拷贝。
  2. 递归结构体:如果结构体存在递归嵌套,实现深拷贝时要小心递归调用,防止栈溢出。可以使用迭代方法或者 Rc/RefCell 等智能指针来处理递归结构。
  3. 未实现 Clone 特质:如果自定义结构体的成员没有实现 Clone 特质,编译器会报错。确保所有成员都实现 Clone 特质,或者手动实现父结构体的 Clone 特质来处理成员的拷贝。