我有两个&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
未在原始指针上实现。
答案 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
并减去它。
(注意:编译器实际上会抱怨并不是那么不安全。)