![](/img/trans.png)
[英]I tried to use a recursion to solve a so-called tribonacci sequence problem
[英]Dealing with so-called global variables in Rust
我們都知道使用全局變量會導致細微的錯誤。 我需要將 Python 程序遷移到 Rust,盡可能保持算法完整。 一旦我證明了 Python-Rust 的等效性,就會有機會調試和更改邏輯以更好地適應 Rust。 這是一個使用全局變量的簡單 Python 程序,后面是我失敗的 Rust 版本。
# global variable
a = 15
# function to perform addition
def add():
global a
a += 100
# function to perform subtraction
def subtract():
global a
a -= 100
# Using a global through functions
print("Initial value of a = ", a)
add()
print("a after addition = ", a)
subtract()
print("a after subtraction = ", a)
這是一個運行的 Rust 程序,但我無法通過閉包來更新所謂的全局變量。
fn fmain() {
// global variable
let mut a = 15;
// perform addition
let add = || {
let mut _name = a;
// name += 100; // the program won't compile if this is uncommented
};
call_once(add);
// perform subtraction
let subtract = || {
let mut _name = a;
// name -= 100; // the program won't compile if this is uncommented
};
call_once(subtract);
// Using a global through functions
println!("Initial value of a = {}", a);
add();
println!("a after addition = {}", a);
subtract();
println!("a after subtraction = {}", a);
}
fn main() {
fmain();
}
fn call_once<F>(f: F)
where
F: FnOnce(),
{
f();
}
我的要求:在 Rust 中重新創建 Python 邏輯。
您的 Rust 代碼沒有使用全局變量, a
變量是堆棧分配的。 雖然 Rust 並不特別支持全局變量,但您當然可以使用它們。 轉換為使用實際全局變量的 Rust,您的程序將如下所示:
use lazy_static::lazy_static;
use parking_lot::Mutex; // or std::sync::Mutex
// global variable
lazy_static! {
static ref A: Mutex<u32> = Mutex::new(15);
}
// function to perform addition
fn add() {
*A.lock() += 100;
}
// function to perform subtraction
fn subtract() {
*A.lock() -= 100;
}
fn main() {
// Using a global through functions
println!("Initial value of a = {}", A.lock());
add();
println!("a after addition = {}", A.lock());
subtract();
println!("a after subtraction = {}", A.lock());
}
如果您更喜歡使用閉包,您也可以這樣做,但是您需要使用內部可變性來允許多個閉包捕獲相同的環境。 例如,您可以使用Cell
:
use std::cell::Cell;
fn main() {
let a = Cell::new(15);
let add = || {
a.set(a.get() + 100);
};
let subtract = || {
a.set(a.get() - 100);
};
// Using a global through functions
println!("Initial value of a = {}", a.get());
add();
println!("a after addition = {}", a.get());
subtract();
println!("a after subtraction = {}", a.get());
}
無依賴示例,如enum
和function
。 編輯:代碼改進,如評論和更正匹配臂中的建議。
use std::sync::{Arc, Mutex, Once};
#[derive(Debug, Clone)]
struct ArcMut<T> {
value: Vec<T>,
}
static START: Once = Once::new();
static mut ARCMUT: ArcMut<Arc<Mutex<u32>>> = ArcMut { value: Vec::new() };
// 作為枚舉
enum Operation {
Add,
Subtract,
}
impl Operation {
// 靜態變化
fn result(self) -> u32 {
let mut arc_clone = unsafe { ARCMUT.value[0].clone() };
let mut unlock = arc_clone.lock().unwrap();
match self {
Operation::Add => *unlock += 100,
Operation::Subtract => *unlock -= 100,
}
*unlock
}
// 動態變化
fn ammount(self, amount: u32) -> u32 {
let mut arc_clone = unsafe { ARCMUT.value[0].clone() };
let mut unlock = arc_clone.lock().unwrap();
match self {
Operation::Add => *unlock += amount,
Operation::Subtract => *unlock -= amount,
}
*unlock
}
}
// 作為函數
fn add() -> u32 {
let mut arc_clone = unsafe { ARCMUT.value[0].clone() };
let mut unlcok = arc_clone.lock().unwrap();
*unlcok += 100;
*unlcok
}
fn main() {
START.call_once(|| unsafe {
ARCMUT = ArcMut {
value: vec![Arc::new(Mutex::new(15))],
}
});
let test = Operation::Add.result();
println!("{:?}", test);
let test = Operation::Subtract.ammount(100);
println!("{:?}", test);
let test = add();
println!("{:?}", test);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.