Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

rust - How to get the byte offset between `&str`

I have two &str pointing to the same string, and I need to know the byte offset between them:

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

    let bar = "baz
quz";
    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
}

This is basically the same as str::find, but since the second slice is a sub-slice of the first, I would have hoped something faster. Also str::find won't work in the lines() case if several lines are identical.

I thought I could just use some pointer arithmetic to do that with something like foo.trim().as_ptr() - foo.as_ptr() but it turns out that Sub is not implemented on raw pointers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

but it turns out that Sub is not implemented on raw pointers.

You can convert the pointer to a usize to do math on it:

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);
}

There's also the unstable method 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);
}

Please be sure to read the documentation for this method as it describes under what circumstances it will not cause undefined behavior.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...