2013-12-09 22 views
5

Tôi đã sau (đủ ngây thơ) mã Rust:không thể mượn foo là bất biến vì nó cũng được vay mượn như có thể thay đổi

let file = &Path(some_file_name); 
let mut buf = [0u8, ..12]; 
match io::file_reader(file) { 
    Ok(reader) => reader.read(buf, buf.len()), 
    Err(msg) => println(msg) 
} 

Các rustc phàn nàn rằng

không thể mượn buf[] như bất biến vì nó là cũng được mượn là có thể thay đổi

Nếu thay đổi dòng tương ứng thành:

Ok(reader) => reader.read(buf, 12), 

tất cả sẽ chỉ hoạt động tốt. Nhưng nó là ít thỏa đáng kể từ bây giờ chiều dài của bộ đệm được nhân đôi trong mã. Mặc dù mơ hồ hiểu tại sao rustc phàn nàn, tôi vẫn muốn tranh luận rằng rustc sẽ có thể suy ra rằng len() là một hàm thuần túy và không có tác dụng phụ sao cho mã đó hợp lệ. Bên cạnh đó, nó là một patten khá phổ biến để đọc vào một bộ đệm theo cách đó.

Vì vậy, cách thức mộc mạc của Rust là gì?

EDIT: Mã dành cho Rust 0.8. Như @pnkfelix đã chỉ ra, API Reader.read đã được thay đổi kể từ đó. Nó không cần tham số thứ hai nữa.

+0

Chăm sóc để cung cấp mã hoàn chỉnh của bạn? Tôi cobbled với nhau một cái gì đó dựa trên mã của bạn nhưng tôi nhận được một lỗi khác nhau. Bạn đang sử dụng phiên bản gỉ nào? – asm

+0

BTW, đường dẫn '~' đang phân bổ một hộp cho 'Đường dẫn', khi một người có thể đặt Đường dẫn thẳng vào ngăn xếp và lấy một tham chiếu bình thường cho nó, ví dụ: '& Đường dẫn'. – huon

+0

Andrew, mã đã bị rỉ sét 0.8. dbaupp, đúng vậy. '& Path' sẽ tốt hơn. – edwardw

Trả lời

7

câu trả lời này là dành cho phiên bản của tôi về rustc: rustc 0,9-trước (61443dc 2013-12-01)

  1. Phiên bản hiện tại của đặc điểm Reader có một giao diện khác so với cái bạn liệt kê. Thay vì lấy cả hai (một lát) một bộ đệm đầu ra và chiều dài, nó bây giờ chỉ mất (một lát) một bộ đệm đầu ra. Nó có thể nhận được độ dài của bộ đệm đầu ra từ slice, vì vậy bạn không cần phải lặp lại chính mình.

  2. Lý do Rust phàn nàn là nó đang cố gắng đảm bảo rằng bạn không có bí danh đọc/ghi bộ nhớ. Nó đang cố gắng ngăn bạn chuyển một khoản vay bất biến của buf vào một ngữ cảnh và một khoản vay có thể thay đổi là buf thành ngữ cảnh khác.

    • Khi bạn nói len() là một chức năng thuần túy, tôi mang nó bạn có nghĩa là nó không viết thư cho bất cứ tiểu bang có thể thay đổi. Tuy nhiên, trong trường hợp chung, có thể là đọc trạng thái có thể thay đổi. (Đó không phải là trường hợp ở đây, vì chúng ta đang đối phó với một bộ đệm kích thước cố định. Tuy nhiên, nói chung người ta có thể tưởng tượng rằng chúng ta đang đối phó với một số trừu tượng mảng tự động thay đổi kích thước.)

    • Vì vậy, có hiệu lực, chỉ là một điều mà mọi người thường không nghĩ đến: đó là đọc.

    • Tôi nghi ngờ cách xử lý thành ngữ với vấn đề bạn đã thấy (bỏ qua thực tế là API đã thay đổi) sẽ tránh được các khoản vay chồng chéo buf, ví dụ:như vậy:

      Ok(reader) => { let l = buf.len(); reader.read(buf, l) },

Bằng cách này, bạn không lặp lại chính mình; bạn chỉ đang cung cấp hai khoảng không chồng chéo, trong đó buf được vay theo nhiều cách khác nhau.

+0

Điều đó có ý nghĩa hoàn hảo. Cảm ơn, pnkfelix. – edwardw

Các vấn đề liên quan