gpt4 book ai didi

rust - 检查一个 &str 是否是另一个 &str 的子片段

转载 作者:行者123 更新时间:2023-12-05 02:42:58 25 4
gpt4 key购买 nike

我需要检查给定的 &str 是否是另一个 &str 的子片段,但我不知道什么是最好的方法。我写了一个函数,它通过使用 str::as_ptr()pointer::offset_from() 来完成这项工作,但它有安全问题,我不知道如何处理它们:

fn is_part_of(outer: &str, part: &str) -> bool {
// SAFETY: not handled
let offset = unsafe { part.as_ptr().offset_from(outer.as_ptr()) };
offset >= 0 && offset + (part.len() as isize) <= outer.len() as isize
}

fn main() {
let hello = "hello";

// Works as expected:
println!("{:?}", is_part_of(hello, &hello[1..5])); // true

// Works as expected, but as far as I understand, this is undefined behaviour:
println!("{:?}", is_part_of(hello, "ello")); // false
}

在 Rust 文档中 pointer::offset_from() , 提到:

Both pointers must be derived from a pointer to the same object.

据我了解,这正是我想要的。

问题

  • 我如何以干净安全的方式编写上面的函数 is_part_of()
  • 作为更好的选择,是否有编译时方法来确保&str 是另一个 &str 的子片段 ?

上下文

我想编写一个结构 SubStr,它包含一个更大的 &str 的子片段,以及对这个更大的 &str 的引用:

#[derive(Debug)]
pub struct SubStr<'src> {
source: &'src str,
part: &'src str, // MUST be a sub-slice of self.source
}

impl<'src> SubStr<'src> {
pub fn new(source: &'src str, part: &'src str) -> Self {
// Here, an assertion is missing, which would ensure that `part` is a sub-slice
// of `source`.
Self { source, part }
}
}

我需要跟踪更大的字符串 (self.source),因为我希望能够通过查看之前剩余的内容来扩展 self.part/在其左/右边界之后,在 self.source 中。

即,我想实现这样的方法:

impl<'src> SubStr<'src> {
/// If we have:
/// self.source = "Hello foo world"
/// self.part = &self.source[10..15] (==> "world")
/// then updates `self.part` to `&self.source[6..15]` (==> "foo world")
pub fn extend_to_one_word_left(&mut self) {
self.part = unimplemented!();
}

/// If we have:
/// self.source = "Hello foo world"
/// self.part = &self.source[6..9] (==> "foo")
/// then updates `self.part` to `&self.source[5..10]` (==> " foo ")
pub fn untrim_spaces(&mut self) {
self.part = unimplemented!();
}
}

最佳答案

代替 pointer::offset_from(),您可以将指针转换为 usize 并使用 usize 算法,这是完全安全的:

fn is_part_of(outer: &str, part: &str) -> bool {
let outer_beg = outer.as_ptr() as usize;
let outer_end = outer_beg + outer.len();
let part_beg = part.as_ptr() as usize;
let part_end = part_beg + part.len();
part_beg >= outer_beg && part_end <= outer_end
}

关于rust - 检查一个 &str 是否是另一个 &str 的子片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67148359/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com