[Rust] 为啥我这里的 p 可以在多个线程间转移所有权并使用呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BBCCBB
V2EX    Rust

[Rust] 为啥我这里的 p 可以在多个线程间转移所有权并使用呢?

  •  
  •   BBCCBB 2022-05-18 15:47:24 +08:00 2113 次点击
    这是一个创建于 1244 天前的主题,其中的信息可能已经有所发展或是发生改变。
     use std::thread; fn main() { struct Point<T> { pub x: T, } let mut p = Point { x: 32 }; let mut vals = Vec::new(); for _ in 0..2 { let h = thread::spawn(move || { p.x = 5; println!("{}", p.x); }); vals.push(h); } for v in vals { v.join().unwrap(); } println!("{}", p.x); // 32 } 输出结果是两个 5 和最后的 32, 也就是说线程里修改对主线程无效 

    playground url: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bf8936b4cc64c1f3124e926e81d9b4d6

    DDDD -_-

    我这里的变量 p 为啥能在多个线程间修改和使用呢? 懂的兄弟带带我, 谢谢.

    同时求一个好的 rust 社区 /论坛 /讨论区

    13 条回复    2022-05-19 11:04:06 +08:00
    reter
        1
    reter  
       2022-05-18 16:15:47 +08:00   1
    我分析,编译器认为只有 p.x 被移动,然后 p.x 默认是 i32 类型, 自动实现了 Copy, 所以在 move 闭包下,创建了新的变量, 复制了 p.x 的值。

    如果 p 里面有其它不可移动的字段,然后在 move 闭包里面 进行了操作,那么无法通过编译。


    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a93e02138c3df6841f402b0ccbb7d7be
    BBCCBB
        2
    BBCCBB  
    OP
       2022-05-18 16:20:22 +08:00
    @reter 有道理, 我再回去好好看看多线程这里. 多谢, 这些小坑烧脑壳
    liuhan907
        3
    liuhan907  
       2022-05-18 17:14:07 +08:00
    @BBCCBB
    你的 p 的具体类型 Point<i32> 字段全满足 Sync ,所以 Point<i32> 也自动满足 Sync ,因此跨线程共享是安全的。你可以尝试用 Point<String> 试试看。
    BBCCBB
        4
    BBCCBB  
    OP
       2022-05-18 18:04:13 +08:00
    @liuhan907 对的, 我也试过这个..

    ```rust
    fn isSync<T: Sync>(_: &T) {}
    isSync(&p);
    ```
    我再去仔细看下 Sync/Send, 多谢.
    BBCCBB
        5
    BBCCBB  
    OP
       2022-05-18 18:05:01 +08:00
    @liuhan907 还有就是我明确使用 move. 但 p 所有权并没有转进去.==
    liuhan907
        6
    liuhan907  
       2022-05-18 18:46:38 +08:00
    @BBCCBB
    和别人交流了一下,这个就是部分捕获。实际上被 move 的是单独的那个 x , @reter 老哥就是对的。
    BBCCBB
        7
    BBCCBB  
    OP
       2022-05-18 20:47:36 +08:00
    @liuhan907 大佬有这方面的文档吗? 以后出了问题我好去翻翻,, 还有就是有啥 rust 论坛吗, dddd
    mr0joker
        8
    mr0joker  
       2022-05-18 23:31:15 +08:00 via iPhone
    rust 官网不就有个交流的地方
    https://users.rust-lang.org/
    mr0joker
        9
    mr0joker  
       2022-05-18 23:32:36 +08:00 via iPhone
    接 8 楼,个人认为那个网站是“好的”
    Buges
        10
    Buges  
       2022-05-19 01:41:59 +08:00 via Android   1
    这是 rust 2021 edition 的新特性 https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html
    move 的只有 x ,而 x 实现了 Copy 。
    BBCCBB
        11
    BBCCBB  
    OP
       2022-05-19 08:57:29 +08:00
    @mr0joker 多谢多谢.
    @Buges 牛逼, 有理有据,令人信服
    reter
        12
    reter  
       2022-05-19 10:54:12 +08:00
    我只知道 struct 可以只 move 部分字段,在闭包里还没见过部分捕获。


    论坛的话,https://rustcc.cn/ 也不错,rustdesk 也在这个论坛上活跃
    BBCCBB
        13
    BBCCBB  
    OP
       2022-05-19 11:04:06 +08:00
    @reter 感谢, 10 楼链接里就是原理了... 新特性,哈哈, 不是 Copy, 是 disjoint capture
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5547 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 09:02 PVG 17:02 LAX 02:02 JFK 05:02
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86