2013-12-09 74 views
5

我有以下(夠單純)防鏽代碼:不能借用富爲永恆不變的,因爲它也被借用爲可變

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) 
} 

rustc抱怨

不能借用buf[]爲永恆不變的,因爲它是也借用爲可變

如果將相應的行更改爲:

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

一切都會正常工作。但是由於現在緩衝區的長度在代碼中是重複的,所以不太令人滿意。雖然模糊地理解爲什麼rustc抱怨,我仍然想要說rustc應該能夠推斷出len()是一個純函數,並且沒有副作用,所以代碼是有效的。另外,以這種方式讀取緩衝區是一個相當常見的模式。

那麼這裏慣用的Rust方式是什麼?

編輯:代碼爲Rust 0.8。正如@ pnkfelix指出的那樣,Reader.read API自那時以來一直在改變。它不再需要第二個參數。

+0

小心提供您的完整代碼?我根據你的代碼拼湊了一些東西,但是我得到了一個不同的錯誤。你使用什麼版本的鐵鏽? – asm

+0

順便說一句,當'Path'爲Path分配一個盒子時,可以將Path直接放在堆棧上並對其進行正常引用,例如, '&Path'。 – huon

+0

安德魯,代碼爲鏽0.8。 dbaupp,的確如此。 '&Path'會更好。 – edwardw

回答

7

這個答案是我的版本rustc的: rustc 0.9預(61443dc 2013年12月1日)

  1. 讀者特質的當前版本比你列出的一個不同的接口。現在只需要(一片)輸出緩衝區,而不是同時輸出一個輸出緩衝區和一個長度。它可以從切片中獲得輸出緩衝區的長度,所以你不需要重複自己。

  2. Rust抱怨的原因是它試圖確保你沒有讀/寫別名的內存。它試圖阻止您將buf的不可變借款傳遞到另一個上下文中,並將buf的可變借款傳遞到另一個上下文中。

    • 當你說len()是一個純粹的功能,我想你的意思是,它並沒有寫入任何可變狀態。但是,在一般情況下,可能是讀數爲可變狀態。 (這裏不是這種情況,因爲我們正在處理一個固定大小的緩衝區,但總的來說,我們可以想象,我們正在處理一些自動調整大小的數組抽象。)

    • 所以有一個效果,只是人們不經常想到的一個:閱讀。

    • 我懷疑處理你所看到的問題的習慣性方式(忽略API已經改變的事實)將避免重疊借用buf,例如,像這樣:

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

這樣,你不要重複自己;你只是提供了兩個不重疊的範圍,其中buf以不同的方式借用。

+0

這很有道理。謝謝,pnkfelix。 – edwardw

相關問題