如何获得`& str`之间的字节偏移量

时间:2016-07-08 13:57:48

标签: rust

我有两个&str 指向相同的字符串,我需要知道它们之间的字节偏移量:

fn main() {
    let foo = "  bar";
    assert_eq!(offset(foo, foo.trim()), Some(2));

    let bar = "baz\nquz";
    let mut lines = bar.lines();
    assert_eq!(offset(bar, lines.next().unwrap()), Some(0));
    assert_eq!(offset(bar, lines.next().unwrap()), Some(4));

    assert_eq!(offset(foo, bar), None); // not a sub-string

    let quz = "quz".to_owned();
    assert_eq!(offset(bar, &quz), None); // not the same string, could also return `Some(4)`, I don't care
}

这与str::find基本相同,但由于第二个切片是第一个切片的子切片,我希望更快。如果多行相同,str::find也不会在lines()情况下起作用。

我以为我可以使用一些指针算法来执行foo.trim().as_ptr() - foo.as_ptr()之类的操作,但事实证明Sub未在原始指针上实现。

2 个答案:

答案 0 :(得分:2)

  

但事实证明Sub未在原始指针上实现。

您可以将指针转换为usize来对其进行数学运算:

fn main() {
    let source = "hello, world";
    let a = &source[1..];
    let b = &source[5..];
    let diff =  b.as_ptr() as usize - a.as_ptr() as usize;
    println!("{}", diff);
}

还有不稳定的方法offset_from

#![feature(ptr_offset_from)]

fn main() {
    let source = "hello, world";
    let a = &source[1..];
    let b = &source[5..];
    // I copied this unsafe code from Stack Overflow without
    // reading the text that told me how to know if this was safe
    let diff = unsafe { b.as_ptr().offset_from(a.as_ptr()) };
    println!("{}", diff);
}

请务必阅读此方法的文档,因为它描述了在什么情况下它不会导致未定义的行为。

答案 1 :(得分:0)

这当然有点不安全,但是如果你想要算术,你可以用usize将指针强加到as并减去它。

(注意:编译器实际上会抱怨并不是那么不安全。)