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

&*这种写法是什么意思?

  •  
  •   gramyang · 2020-05-21 22:52:03 +08:00 · 3408 次点击
    这是一个创建于 1679 天前的主题,其中的信息可能已经有所发展或是发生改变。
    let mut v = String::from("hello");
    assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v));

    这里的 get_mut 是 str 的方法,其返回一个&mut str,这里的&*我猜测是将&mut str 给转换成了&str 。
    请大佬指点。
    第 1 条附言  ·  2020-05-22 06:03:43 +08:00
    pub fn l_t4(){
    let a = 5;
    let b = &a;
    let c = &a;//可以存在多个不可变引用,不能和可变引用共存
    println!("{:p} {:p} {:p} {:p}",&a,&&a,&&&a,&&&&a);//四个地址都不同
    println!("{:p} {:p}",b,c);//两个地址相同
    let mut a1 = 6;
    let b1 = &mut a1;//只能有一个可变引用,且可变引用和不可变引用不能共存
    let c1 = &*b1;//*消除了 mut,获取了一个不可变引用
    let e1 = &*b1;//可以通过可变引用获取多个不可变引用
    println!("{:p} {:p} {:p}",b1,c1,e1);//三个地址相同
    }

    由此可以看出&*共存的写法一般都是用来通过可变引用生成不可变引用,从而用另一种方式达成可变引用和不可变引用共存。
    第 2 条附言  ·  2020-05-25 08:57:28 +08:00
    目前看来,&*还可以用来解裸指针:
    let mut num=5;
    let r1 = &num as *const i32;
    let r2 = &mut num as *mut i32;
    let r3 = unsafe{&*r2};
    let r4 = unsafe {&*r1};
    unsafe{
    println!("{:p} {:p} {:p} {:p}",r1,r2,r3,r4); //四个地址一致
    }
    let mut a = Box::new(num);
    let raw = &mut *a; //这种写法不用 as
    println!("{:p}",raw); //地址和上面不一致
    2 条回复    2021-10-07 11:31:17 +08:00
    zhizunzz
        1
    zhizunzz  
       2020-05-22 06:50:46 +08:00 via Android
    *是智能指针的解引用,&是引用好理解,你可以先不看&,搜下智能指针的资料
    versee
        2
    versee  
       2021-10-07 11:31:17 +08:00
    一个类型之所以能当智能指针用是因为它实现了 Deref 这个 trait,以 String 为例,它 impl Deref 的时候写了 type Target=str,而当对这种类型进行解引用的时候得到的就是 Deref 中定义的这个 Target 的类型,所以对一个 String 类型解引用得到的是 str 类型,再加上&,得到的自然就是&str 类型。这也是&*写法的原因:某智能指针类型在解引用再加引用的过程中由于 Target 的存在,最终的得到的类型会发生变化。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5422 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 09:06 · PVG 17:06 · LAX 01:06 · JFK 04:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.