2015-05-29 6 views
7
let mut result = String::with_capacity(1000); 

result.push_str("things... "); 
result.push_str("stuff... "); 

result.truncate((result.len() - 4)); 

Dies ist jedoch ein Kompilierungsfehler. Etwas mit dem Border Checker zu tun und möglicherweise Wandelbarkeit.Kann nicht als unveränderlich ausleihen - String und len()

error[E0502]: cannot borrow `result` as immutable because it is also borrowed as mutable 
--> <anon>:7:22 
    | 
7 |  result.truncate((result.len() - 4)); 
    |  ------   ^^^^^^   - mutable borrow ends here 
    |  |    | 
    |  |    immutable borrow occurs here 
    |  mutable borrow occurs here 

Doch wenn ich es mir erlaubt ist etwas ändern, dies zu tun:

let newlen = result.len() - 4; 
result.truncate(newlen); 

Warum? Gibt es eine Möglichkeit, dies zu ändern, so dass es in einer Zeile geschrieben werden kann? (P.S. Dies ist auf Rust 1.0)

Antwort

9

Dies ist ein unglücklicher Mangel von Rust Border Prüfverfahren. Dies geschieht im Wesentlichen weil

result.truncate(result.len() - 2) 

äquivalent zu

String::truncate(&mut result, result.len() - 2) 

und hier kann man sehen, dass da Argumente von links nach rechts, um berechnet werden, wird result tatsächlich geliehenen mutably, bevor es in result.len() verwendet wird .

Ich habe dieses Problem in Rust Problem Tracker gefunden: #6268. Dieses Problem wurde zugunsten von non-lexical borrows RFC issue geschlossen. Es scheint, dass es nur eines dieser Dinge ist, die schön wären, aber die mehr Zeit brauchen, um es zu erledigen, dass es vor 1.0 verfügbar war. This Post kann auch von Interesse sein (obwohl es fast zwei Jahre alt ist).

+0

Das hilft zu klären. Es ist mehr ein Ärgernis als alles andere. Der Fehler hängt also mit einem Konflikt zwischen "truncate", der eine Mutabilität benötigt, und "len", der eine Unveränderbarkeit benötigt, zusammen. Es scheint so, als ob "result.len()" seine Arbeit abgeschlossen hätte, bevor die Übergabe abgebrochen werden würde, was bedeutet, dass dies eher eine Kompilierer-Eigenart ist als alles andere? http://doc.rust-lang.org/std/string/struct.String.html#method.len – jocull

+0

Sie sind fast richtig - das Problem ist, dass 'truncate' erfordert' & mut self', die * any * anschließt verbietet Kredite im gleichen Umfang. Und ja, es scheint, dass "result.len()" abgeschlossen ist, bevor es an "truncate()" übergeben wird, aber meine Antwort erklärt, warum es nicht so ist - tatsächlich wird die Methode Empfänger * zuvor berechnet * arguments, und so '& mut result' ist im scope * bevor *' & result' von 'result.len()' benötigt wird. –

+0

@jocull, Sie können mehr in den Ausgaben finden, die ich in meinem Update verknüpft habe, wenn Sie daran interessiert sind. –

Verwandte Themen