• rust实战 newtype模式


    什么是newtype

    简单的说,就是用元组结构体将已有类型包裹起来:struct Meters(u32)

    newtype的优点:

    • 自定义类型可以让我们给出更有意义和可读性的类型名,比如struct Year(u32)
    • 某些场景,只有newtype可以很好的解决
    • 隐藏内部类型的细节

    自定义类型给出更有意义的命名

    struct Years(i64);
    
    struct Days(i64);
    
    impl Years {
        pub fn to_days(&self) -> Days {
            Days(self.0 * 365)
        }
    }
    
    
    impl Days {
        /// truncates partial years
        pub fn to_years(&self) -> Years {
            Years(self.0 / 365)
        }
    }
    
    

    在外部类型上实现外部trait

    rust限定只有当类型和对应trait中的任意一个定义在本地包内时,才能够为该类型实现trait,叫做孤儿规则
    比如你不能Vec实现fmt::Display。

    通过newtype类型可以绕过孤儿规则,实现是利用元组结构体创建出新的类型。并且不会造成任何运行时开销,新类型会在编译过程中被优化掉。

    use std::{fmt, ops::Deref};
    
    struct Wrapper(Vec<String>);
    
    impl fmt::Display for Wrapper {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "[{}]", self.0.join(", "))
        }
    }
    
    impl Deref for Wrapper {
        type Target = Vec<String>;
    
        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }
    
    fn main() {
        let w = Wrapper(vec![String::from("hello"),
        String::from("world")]);
        println!("w = {}", w);
        println!("wrapper can use vec function join, join result is: {}", w.join(","));
    }
    

    因为Wrapper是一个新的类型,所以它没有自己内部值的方法。为了让Wrapper的行为与Vec完全一致,我们需要在Wrapper中实现所有Vec的方法,并将这些方法委托给self.0。假如我们希望新类型具有内部类型的所有方法,那么我们也可以为Wrapper实现Deref trait来直接返回内部的类型。假如我们不希望Wrapper类型具有内部类型的所有方法,比如在需要限制Wrapper类型的行为时,我们就只能手动实现需要的那部分方法了。

    封装内部细节

    #[derive(Debug)]
    struct WrapperStr(String);
    
    fn main() {
        let s = "Hello World".to_string();
        let mut w = WrapperStr(s);
        println!("{:?}", w);
        
        // 隐藏了被包装String的方法
        // 但仍然可以通过下面方式调用
        // w.0.push_str(" !");
        // println!("{:?}", w);   
    }
    
    
  • 相关阅读:
    (二十九)动态单元格
    (二十八)QQ好友列表的展开收缩
    (二十七)QQ好友列表的实现
    (二十六)静态单元格(Cell)
    (二十五)键盘的设置与TextField细节处理
    poj 1734 Sightseeing trip
    BZOJ 2200: [Usaco2011 Jan]道路和航线
    LUOGU P1073 最优贸易
    poj 3662 Telephone Lines
    poj 3539 Elevator
  • 原文地址:https://www.cnblogs.com/linyihai/p/15877521.html
Copyright © 2020-2023  润新知