[英]How do I remove the elements of vector that occur in another vector in Rust?
[英]How can I modify elements of a vector in place in Rust?
我試圖將對Vec
(切片)的不可變引用傳遞給一個函數,該函數將用遞增的值填充Vec
,然后對其進行迭代,再次將其替換為零。
我的想法是向量是不可變的(向量的數據類型和大小永遠不會改變),但是向量的內容應該是對整數的可變引用。 還是它們應該是整數本身(而不是引用)的實際值?
事實證明,這是一項艱巨的任務。.我已經閱讀了有關可變性和借用的知識,並且我對此感到很了解。 我對C中的引用,解引用,指針等如何工作有一個粗略的了解,但是我認為我在Rust的語法中苦苦掙扎來實現這一點。
我在想這個錯誤的方式嗎? 在Rust中,創建潛在的巨大Vec
的副本,對其進行操作並返回它是否更加慣用?
到目前為止,這是我的代碼(無法編譯,有很多錯誤):
#![feature(iterator_step_by)]
pub fn nth(n: usize) {
let size: usize = (2 as f64 * n as f64 * (n as f64).ln()) as usize;
// Set an upper bound for seiving.
let size_sqrt: usize = (size as f64).sqrt().ceil() as usize;
let nums: Vec<&mut usize> = Vec::with_capacity(size);
sieve(nums, &size, &size_sqrt);
}
fn sieve(nums: [&mut usize], size: &usize, size_sqrt: &usize) {
for i in 0..*size {
nums[i] = i;
}
for num in nums {
if num < 2 {
continue;
} else if num > *size_sqrt {
break;
}
for x in (num.pow(2)..size).step_by(*num) {
nums[x] = 0;
}
}
}
我的想法是向量是不可變的(向量的數據類型和大小永遠不會改變),但是向量的內容應該是對整數的可變引用。 還是它們應該是整數本身(而不是引用)的實際值?
引用( &'a T
和&'a mut T
)只能引用另一個值擁有的值。 引用不能擁有其引用對象。
如果要具有對集合中某些不一定是連續的整數進行運算的函數,則構建一個整數引用向量可能是一個好主意。 但是,根據您的代碼示例,情況似乎並非如此。 向量擁有整數將變得更加容易和容易。 這意味着向量本身將需要是可變的。 但是,如果要確保函數不嘗試更改向量的大小,則該函數可以接受可變的整數切片&mut [usize]
,而不是對向量的可變引用( &mut Vec<usize>
)。
在Rust中,創建潛在的巨大
Vec
的副本,對其進行操作並返回它是否更加慣用?
這取決於之后是否需要再次使用原始Vec
。 如果您不這樣做,那么就地對Vec
進行突變會更有效。 如果在某些情況下只需要保留原始Vec
,而在其他情況下則不需要,則可以始終預先clone()
Vec
。 如果確實每次都需要原始Vec
,則返回新Vec
可能會更有效,特別是如果您可以使用collect
從迭代器填充它,因為這將嘗試提前分配正確的大小並僅分配每個Vec
Vec
值一次。
考慮到所有這些,這就是我編寫代碼的方式。 請注意,我不得不改變主sieve
的主循環,以使其不直接遍歷nums
,因為這會導致借入沖突– for
循環需要對nums
進行借入,但是賦值nums[x]
也將嘗試進行可變借入nums
而其他借項處於活動狀態。 我還將&usize
參數更改為usize
,因為對小型可復制類型(例如原始整數)使用引用沒有任何好處(實際上,它可能會稍慢一些)。
#![feature(iterator_step_by)]
pub fn nth(n: usize) {
let size: usize = (2.0 * n as f64 * (n as f64).ln()) as usize;
// Set an upper bound for seiving.
let size_sqrt: usize = (size as f64).sqrt().ceil() as usize;
let mut nums: Vec<usize> = vec![0; size];
sieve(&mut nums, size, size_sqrt);
}
fn sieve(nums: &mut [usize], size: usize, size_sqrt: usize) {
for i in 0..size {
nums[i] = i;
}
for i in 0..size {
let num = nums[i];
if num < 2 {
continue;
}
if num > size_sqrt {
break;
}
for x in (num.pow(2)..size).step_by(num) {
nums[x] = 0;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.