2016-07-08 5 views
3

Ich habe zwei &strauf demselben String zeigt, und ich brauche das Byte zu wissen, zwischen ihnen gegenüber:Wie das Byte erhalten Versatz zwischen `& 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 
} 

Diese im Grunde die gleichen wie str::find ist , aber da die zweite Scheibe eine Unterscheibe der ersten ist, hätte ich etwas schneller gehofft. Auch str::find funktioniert nicht im lines() Fall, wenn mehrere Zeilen identisch sind.

Ich dachte, ich könnte nur einige Zeigerarithmetik verwenden, um das mit etwas wie foo.trim().as_ptr() - foo.as_ptr() zu tun, aber es stellt sich heraus, dass Sub nicht auf unformatierten Zeigern implementiert ist.

Antwort

2

aber es stellt sich heraus, dass Sub nicht auf unformatierten Zeigern implementiert ist.

Sie können den Zeiger auf eine usize konvertieren Mathematik zu tun drauf:

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

Könnte ein 'isize' hier verwendet werden sollen, da' .Offset (...) 'erwartet ein' isize' Argument sowieso; Es wird Sie vor Problemen bewahren, wenn 'b' kleiner als' a' ist. –

+0

@MatthieuM. Ich denke nicht, dass "Offset" * hier verwendet werden sollte. Außerdem möchte OP das gleiche wie "str :: find" zurückgeben, was "Option " wäre. – Shepmaster

0

Das ist natürlich Art unsicher, aber wenn Sie arithmetische möchten, können Sie werfen nur die Zeiger auf usize mit as und subtrahieren Sie das.

(Hinweis: Es ist nicht so unsicher ist, dass der Compiler tatsächlich beschweren.)

+0

Es ist überhaupt nicht unsicher *. Zeiger sind nur Zahlen. Der Zugriff auf Speicher an einem beliebigen Ort ist unsicher. – Shepmaster

+0

Aber das Ergebnis ist absoluter Unsinn in diesem Fall, wenn die Slices nicht aus der gleichen Zeichenfolge sind. –

+0

Sicherlich. Aber ** unsicher hat in Rust eine spezifische Bedeutung und wir sollten den Begriff nicht missbrauchen, da dies nur zukünftige Leser verwirren wird. – Shepmaster

Verwandte Themen