我知道一般来说,全局变量是要避免的,但是,我认为在实际意义上,有时候使用它们是可取的(在变量是程序的组成部分的情况下)。
为了学习Rust,我正在用sqlite3和GitHub上的Rust/sqlite3包编写一个数据库测试程序。因此,(在我的测试程序中)(作为一个全局变量的替代),必须在函数之间传递数据库变量,函数之间大约有12个。下面是一个例子。
1.在Rust中使用全局变量是否可能、可行和可取?
1.在下面的例子中,我可以声明和使用一个全局变量吗?
extern crate sqlite;
fn main() {
let db: sqlite::Connection = open_database();
if !insert_data(&db, insert_max) {
return;
}
}
我尝试了以下操作,但似乎不太正确,并导致以下错误(我也尝试了unsafe
块):
extern crate sqlite;
static mut DB: Option<sqlite::Connection> = None;
fn main() {
DB = sqlite::open("test.db").expect("Error opening test.db");
println!("Database Opened OK");
create_table();
println!("Completed");
}
// Create Table
fn create_table() {
let sql = "CREATE TABLE IF NOT EXISTS TEMP2 (ikey INTEGER PRIMARY KEY NOT NULL)";
match DB.exec(sql) {
Ok(_) => println!("Table created"),
Err(err) => println!("Exec of Sql failed : {}\nSql={}", err, sql),
}
}
编译导致的错误:
error[E0308]: mismatched types
--> src/main.rs:6:10
|
6 | DB = sqlite::open("test.db").expect("Error opening test.db");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found struct `sqlite::Connection`
|
= note: expected type `std::option::Option<sqlite::Connection>`
found type `sqlite::Connection`
error: no method named `exec` found for type `std::option::Option<sqlite::Connection>` in the current scope
--> src/main.rs:16:14
|
16 | match DB.exec(sql) {
| ^^^^
7条答案
按热度按时间0pizxfdo1#
这是可能的,但是不允许直接进行堆分配。堆分配是在运行时执行的。下面是一些示例:
2skhul332#
只要静态变量是线程局部变量,就可以很容易地使用它们。
缺点是这个对象对于你的程序可能产生的其他线程来说是不可见的。优点是不像真正的全局状态,它是完全安全的,使用起来也不痛苦--真正的全局状态在任何语言中都是一个巨大的痛苦。下面是一个例子:
这里我们创建一个线程局部静态变量,然后在函数中使用它。注意,它是静态的和不可变的;这意味着它所驻留的地址是不可变的,但是由于
RefCell
,该值本身将是可变的。与常规的
static
不同,在thread-local!(static ...)
中可以创建几乎任意的对象,包括那些需要堆分配进行初始化的对象,如Vec
、HashMap
等。如果你不能马上初始化这个值,例如,它依赖于用户输入,你可能还必须在那里抛出
Option
,在这种情况下,访问它会变得有点笨拙:m2xkgtsf3#
看看
const
andstatic
section of the Rust book。您可以使用类似下面的内容:
或
在全球范围内。
但是这些是不可变的,对于可变性,你可以使用如下的语句:
然后引用它们如下:
v440hwme4#
我是Rust的新手,但这个解决方案似乎很有效:
另一个解决方案是将横梁通道发送/接收对声明为不可变的全局变量。通道应是有界的,并且只能保存一个元素。初始化全局变量时,将全局示例推入通道。使用全局变量时,弹出通道以获取它,并在使用完它后将其推回。
这两种解决方案都应该提供使用全局变量的安全方法。
3phpmpom5#
如果使用lazy_static宏(如the documentation中所示),则可以为静态变量分配堆:
使用这个宏,静态变量可能需要在运行时执行代码才能被初始化,这包括任何需要堆分配的东西,如向量或哈希Map,以及任何需要计算函数调用的东西。
vptzau2j6#
我认为这一页涵盖了大部分方面
42fyovps7#
夜间使用板条箱
once_cell
或lazy_static
或SyncOnceCell。