• 罗杰
    2021-11-05
    先把safe rust 弄清楚,再考虑 unsafe 的事

    作者回复: 对!

    
    1
  • TheLudlows
    2021-11-16
    pub fn as_mut_ptr(&mut self) -> *mut u8 { self as *mut str as *mut u8 } 请问老师这个转换为什么要多一层 *mut str ,as *mut str 和 as *mut u8的区别是什么,还有说这个as 转换的过程做了什么

    作者回复: as 不会做什么,只是把一种类型当成另一种类型处理。第一个转换是把 &str 引用转换成对应的裸指针,第二个是把裸指针从一种类型转换成另一种类型。

    
    
  • D. D
    2021-11-06
    不能直接使用 get_unchecked_mut() 去实现,因为即使在 unsafe 代码里面也不能对一个变量同时进行多个可变借用,需要先转换成裸指针。 不知道这样实现可以吗? fn split_mut(s: &mut str, sep: char) -> Option<(&mut str, &mut str)> { let pos = s.find(sep); pos.map(|pos| { let len = s.len(); let sep_len = sep.len_utf8(); let ptr1: *mut u8 = s.as_mut_ptr(); let ptr2: *mut u8 = s[(pos + sep_len)..].as_mut_ptr(); unsafe { let s1 = std::slice::from_raw_parts_mut(ptr1, pos); let s2 = std::slice::from_raw_parts_mut(ptr2, len - (pos + sep_len)); (std::str::from_utf8_unchecked_mut(s1), std::str::from_utf8_unchecked_mut(s2)) } }) } https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=98493d711d7a002c318aace31ecb2af0
    展开

    作者回复: 嗯,是这个思路。用 ptr.add() 来处理指针会更好。参考代码见:https://github.com/tyrchen/geektime-rust/blob/master/30_unsafe/examples/split.rs#L26

    
    
  • 终生恻隐
    2021-11-05
    fn split_mut(s: &mut str, sep: char) -> Option<(&mut str, &mut str)> { let pos = s.find(sep); pos.map(|pos| unsafe { let len = s.len(); let sep_len = sep.len_utf8(); let ss = s.as_mut_ptr(); let mut scl = &mut *(slice_from_raw_parts_mut(ss, pos)); let mut scr = &mut *( slice_from_raw_parts_mut( ss.offset((pos + sep_len) as isize), len-(pos + sep_len) ) ); // println!("left {}", from_utf8_unchecked_mut(scl)); // println!("left {}", from_utf8_unchecked_mut(scr)); (from_utf8_unchecked_mut(scl), from_utf8_unchecked_mut(scr)) }) }

    作者回复: 嗯,思路是对的。参考代码:https://github.com/tyrchen/geektime-rust/blob/master/30_unsafe/examples/split.rs#L26

    
    
  • pedro
    2021-11-05
    因为 Send / Sync 是 auto trait,所以大部分情况下,你自己的数据结构不需要实现 Send / Sync,然而,当你在数据结构里使用裸指针时,因为裸指针是没有实现 Send/Sync 的,连带着你的数据结构也就没有实现 Send/Sync。但很可能你的结构是线程安全的,你也需要它线程安全。 但很可能你的结构是线程安全的,你也需要它线程安全? 这句话我咋理解不了啊,是线程安全的,咋还需要它线程安全?

    作者回复: 你如果可以保证它线程安全的话,需要实现 Send/Sync 告诉编译器它线程安全。否则编译器会报错。

    共 5 条评论
    
  • 杨学者
    2023-09-02 来自上海
    let arr: [usize; 6] = unsafe { std::mem::transmute(map) }; 新版的rust1.72stable报错了,因为hashmap的源码更新了
    
    
  • 约书亚
    2022-10-04 来自德国
    fn split_mut(s: &mut str, sep: char) -> Option<(&mut str, &mut str)> { let pos = s.find(sep); pos.map(|pos| { let len = s.len(); let sep_len = sep.len_utf8(); let p = s.as_mut_ptr(); unsafe { let s1 = from_raw_parts_mut(p, pos); let s2 = from_raw_parts_mut(p.add(pos + sep_len), len - pos - sep_len); (from_utf8_unchecked_mut(s1), from_utf8_unchecked_mut(s2)) } }) }
    
    
  • 进击的Lancelot
    2022-09-17 来自广东
    关于思考题,我的实现: ```rust fn split_mut(s: &mut str, sep: char) -> Option<(&mut str, &mut str)> { let pos = s.find(sep); pos.map(|pos| { let len = s.len(); let sep_len = sep.len_utf8(); let s1 = s.get_mut(0..pos).unwrap().as_mut_ptr(); let s2 = s.get_mut(pos + sep_len..len).unwrap().as_mut_ptr(); unsafe { let s1 = from_raw_parts_mut(s1, pos); let s2 = from_raw_parts_mut(s2, len - pos - sep_len); (from_utf8_unchecked_mut(s1), from_utf8_unchecked_mut(s2)) } }) } ``` playground 连接: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7be8e52e1278665816a03eb30fbfaf60
    展开
    
    