2015-07-19 20 views
6

Jeśli sprawdzeniu docs for Read, większość metod zaakceptować &mut self. Ma to sens, ponieważ odczyt z czegoś zwykle aktualizuje wewnętrzne przesunięcie, aby następny odczyt zwracał inne dane. Jednak to kompiluje:Dlaczego możliwe jest zaimplementowanie Read na niezmiennym odnośniku do pliku?

use std::io::Read; 
use std::fs::File; 

fn main() { 
    let file = File::open("/etc/hosts").unwrap(); 
    let vec = &mut Vec::new(); 
    (&file).read_to_end(vec).unwrap(); 
    println!("{:?}", vec); 
} 

Plik nie jest zmienny, ale dane są odczytywane z pewnością w ten wydaje mi się błędna.. It was pointed out that there is an impl<'a> Read for &'a File, ale fakt, że niezmienna instancja jest pozornie zmutowana, wciąż wydaje się dziwny.

+1

Czy odpowiedź na [Dlaczego nie mogę zadzwonić File.take() na odniesienie?] (Http://stackoverflow.com/q/31503429/395760) rozwiązać ten czy pytasz * dlaczego * 'Read' jest zaimplementowano w '& File'? – delnan

+1

@delnan Pytanie brzmi: dlaczego 'i plik' wystarczy? Należy oczekiwać pliku '& mut file'. – mdup

+1

@delnan (Nie zadawałem pytania, ale) Nie sądzę, że odpowiedź na to pytanie. Musi być coś jeszcze. 'read_to_end' powinno działać na' 'mut plik' lub' & mut & file', ale '(& file)' nie należy do tych. – fjh

Odpowiedz

7

Jak wskazano @kennytm, a.read_to_end(vec) jest odpowiednikiem Read::read_to_end(&mut a, vec), więc (&file).read_to_end(vec) rozszerza się do Read::read_to_end(&mut &file, vec). W tym ostatnim wyrażeniu &file jest nową wartością tymczasową typu &File. Nie ma problemu z przyjmowaniem zmiennych odniesień do wyrażenia (na przykład &mut 42). Dokładnie to się dzieje tutaj. Fakt, że wyrażenie jest odniesieniem do niezmiennej wartości, nie ma znaczenia, ponieważ nie możemy faktycznie zmutować wartości przez &mut &T.

Jeśli chodzi o pytanie, dlaczego nie potrzebujemy, aby zmienna File była zmienna: File to po prostu nowy deskryptor pliku, tzn. Indeks do tabeli otwartego pliku zarządzanej przez system operacyjny. read i przyjaciele nie będą w ogóle zmienić ten deskryptor, który jest dlaczego File nie musi być zmutowany. Istnieje oczywiście mutacja, ale dzieje się tak przez system operacyjny we własnych strukturach danych, a nie w kodzie rdzy użytkownika.

+3

+1 za "mutację [...] wykonuje system operacyjny na własnych strukturach danych, a nie w kodzie rdzy użytkownika." Wierzyłem, że posiadanie (immut) '& pliku' oznacza, że ​​nic nie może się zdarzyć twojemu plikowi; ta odpowiedź pokazuje, że tak nie jest, co jest sprzeczne z intuicją IMO. Może to zasługuje na wyjaśnienie w dokumentach. – mdup

+1

@mdup może to po prostu najlepsze dla nas, aby myśleć o 'file' jako posiadające [komórki] (http://doc.rust-lang.org/std/cell/index.html) jakiegoś rodzaju. – Shepmaster

+2

@Shepmaster: Tak, to tak, jakby plik miał własny wbudowany muteks. System operacyjny dba o jego synchronizację. – sellibitze

Powiązane problemy