V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
steins2628
V2EX  ›  Rust

Rust 当自定义结构体含 String 类型时 无法 derive Copy 应该怎么解决?

  •  
  •   steins2628 · 2022-08-23 16:41:00 +08:00 · 1712 次点击
    这是一个创建于 608 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如现在一个结构体是

    #[derive(Copy, Clone, Serialize, Deserialize)]
    pub struct Setting {
        pub language: String,
        pub version: String,
        pub updata: bool
    }
    
    // IDE 提示
    th trait `Copy` may not be implemented for this type
    

    查资料找到原因是因为有 String 类型变量 Can’t derive Copy because of String?, 大致意思理解为由于 String 是可变长的,在 Copy 的过程中可能会导致一些问题?

    尝试将类型改 str 后报同样的错误,如果结构体中含有 Vec 数组的话也是同样的错误

    如果结构体就是需要 String 和 Vec 类型的数据并且想要 derive Copy 的话有什么办法吗?或者说有什么更好的方法来定义这个结构体?

    7 条回复    2022-08-25 13:37:07 +08:00
    hsfzxjy
        2
    hsfzxjy  
       2022-08-23 17:39:10 +08:00 via Android   ❤️ 1
    个人认为要 copy 时写.clone()更直观,毕竟这个类型的拷贝不是 trivial 的
    steins2628
        3
    steins2628  
    OP
       2022-08-23 17:43:32 +08:00
    @kuviki 感谢大佬指点,大部分加了生命周期后都修好了,但是如果是 Vec 类型就继续报错
    ```rust
    pub struct Setting<'a> {
    pub some_list: Vec<&'a str<'a>>
    pub another_list: Vec<&'a myStrct<'a>>
    }
    ```
    Vec str 加上这样的生命周期后会报错 lifetime argument not allowed, 主要是 str<'a> , 改为 Vec<&'a str> 后报错 this field does not implement `Copy`

    如果是自定义的结构体 myStruct 会报错 this field does not implement `Copy`

    在 StackOverflow 上找到的一篇回答说是要加两个生命周期修饰,像回答里说的那样加上又会显示 undeclared item 'b
    https://stackoverflow.com/questions/54984969/rust-lifetime-in-vect-convoluted-syntax

    这样子的数据应该怎么正确地加上生命周期呢?
    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f036b4bf786d75c567a965fef7917064
    kuviki
        4
    kuviki  
       2022-08-23 17:53:36 +08:00
    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=941271e72be6a8cb7053e5c8214988b0
    这样子加


    另外,如果能接受内存泄露的代价,也可以用 Box::leak 把 String 和 Vec 转成 &'static 引用
    steins2628
        5
    steins2628  
    OP
       2022-08-24 09:14:50 +08:00
    @kuviki 终于编译过了,谢谢指点

    @hsfzxjy 也试了下 clone ,比都加生命周期方便了不少,谢谢
    SingeeKing
        6
    SingeeKing  
       2022-08-25 11:41:45 +08:00
    不要滥用 Copy !!

    Rust 的移动比你想象中要多得多,Copy 会导致每一次看似低成本的移动都会拷贝大量的内存;应当显示使用 Clone 而不是 Copy
    steins2628
        7
    steins2628  
    OP
       2022-08-25 13:37:07 +08:00
    @SingeeKing 原来是这样,现在用的就是 Clone ,因为生命周期还不熟,到后面总是有新问题出现,谢谢大佬提醒
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5386 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 07:25 · PVG 15:25 · LAX 00:25 · JFK 03:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.