我正在嘗試利用函式式編程和遞回在 rust 中創建用戶輸入驗證函式。如何回傳一個不可變向量,其中一個元素連接到末尾?
fn get_user_input(output_vec: Vec<String>) -> Vec<String> {
// Some code that has two variables: repeat(bool) and new_element(String)
if !repeat {
return output_vec.add_to_end(new_element); // What function could "add_to_end" be?
}
get_messages_from_user(output_vec.add_to_end(new_element)) // What function could "add_to_end" be?
}
其他所有功能都有:
push將可變向量添加到可變向量
append將元素添加到可變向量的末尾將不可變向量添加
concat到不可變向量
???將元素添加到不可變向量的末尾
我能做到的唯一解決方案開始作業正在使用:
[write_data, vec![new_element]].concat()
但這似乎效率低下,因為我只為一個元素制作了一個新向量(因此在編譯時知道大小)。
uj5u.com熱心網友回復:
您將 Rust 與只參考物件的語言混淆了。在 Rust 中,代碼可以擁有物件的獨占所有權,因此您無需在更改可以共享的物件時那么小心,因為您知道該物件是否是共享的。
例如,這是有效的 JavaScript 代碼:
const a = [];
a.push(1);
這是有效的,因為a它不包含陣列,它包含對陣列的參考。const防止a被重新指向不同的物件,但它不會 使陣列本身不可變。
因此,在這些型別的語言中,純函式式編程試圖避免改變任何狀態,例如將專案推送到作為引數的陣列上:
function add_element(arr) {
arr.push(1); // Bad! We mutated the array we have a reference to!
}
相反,我們這樣做:
function add_element(arr) {
return [...arr, 1]; // Good! We leave the original data alone.
}
鑒于您的函式簽名,您在 Rust 中擁有的是完全不同的場景! 在您的情況下,output_vec它歸函式本身所有,程式中沒有其他物體可以訪問它。因此,如果這是您的目標,則沒有理由避免對其進行變異:
fn get_user_input(mut output_vec: Vec<String>) -> Vec<String> {
// Add mut ^^^
您必須記住,任何非參考都是擁有的值。&Vec<String>將是對其他人擁有的向量的不可變參考,但這Vec<String>是該代碼擁有且其他人無權訪問的向量。
不相信我?這是一個簡單的損壞代碼示例,可以證明這一點:
fn take_my_vec(y: Vec<String>) { }
fn main() {
let mut x = Vec::<String>::new();
x.push("foo".to_string());
take_my_vec(x);
println!("{}", x.len()); // E0382
}
該運算式x.len()會導致編譯時錯誤,因為向量x已移至函式引數中,而我們不再擁有它。
那么為什么函式不應該改變它現在擁有的向量呢?呼叫者不能再使用它了。
In summary, functional programming looks a bit different in Rust. In other languages that have no way to communicate "I'm giving you this object" you must avoid mutating values you are given because the caller may not expect you to change them. In Rust, who owns a value is clear, and the argument reflects that:
- Is the argument a value (
Vec<String>)? The function owns the value now, the caller gave it away and can't use it anymore. Mutate it if you need to. - Is the argument an immutable reference (
&Vec<String>)? The function doesn't own it, and it can't mutate it anyway because Rust won't allow it. You could clone it and mutate the clone. - Is the argument a mutable reference (
&mut Vec<String>)? The caller must explicitly give the function a mutable reference and is therefore giving the function permission to mutate it -- but the function still doesn't own the value. The function can mutate it, clone it, or both -- it depends what the function is supposed to do.
If you take an argument by value, there is very little reason not to make it mut if you need to change it for whatever reason. Note that this detail (mutability of function arguments) isn't even part of the function's public signature simply because it's not the caller's business. They gave the object away.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/426857.html
下一篇:嵌套的zip內容串列
