为什么必须在 Rust 中初始化结构?
Why must be structure initialized in rust?
在 C 中,我可以使用尚未初始化的结构。我在 Rust 中尝试了这段代码:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main(){
let mut user1: User;
user1.active = false;
}
但它产生了一个编译错误:
error[E0381]: assign to part of possibly-uninitialized variable: `user1`
--> src/main.rs:10:5
|
10 | user1.active = false;
| ^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `user1`
为什么这在 C 中是允许的,但在 Rust 中是错误的?
如果要安全地访问 Rust 中的 All 值,它们必须具有初始化值。
这是因为使用未初始化值的操作具有未定义的行为。这可能会导致编译器意外地错误编译您的代码。
避免错误编译是 Rust 的主要目标之一;包括其他形式的未定义行为,例如数据竞争、取消引用无效指针或更改其他代码假定不会更改的数据。阅读更多 here。
在 C 中,您可以访问这些值;从而允许编译器在您违反合同后错误编译您的代码。然而,在 Rust 中,你不能这样做。
在某些语言中,例如 C#,您可以用 null
替换未初始化的值。我们有一个类似的概念:Option
s,要么是Some(value)
,要么有None
。
请注意,如果编译器由于与不合理操作相关的未定义行为而错误编译您的代码,这不是编译器的错。它也不是要寻找这个;它只是在尝试优化您的代码。如果我给你一根棒球棒,你用它打你的头,那么你就是在滥用它,作为设计师,这不是我的错,因为我无法预见你会滥用它。
有 种方法可以完成您可以在 C 中完成的工作。这些是 unsafe
并且强烈建议不要进行常规操作,因此请在跳入不必要的 unsafe
和可能不合理的行为之前尽最大努力寻找其他解决方案。
在涉足unsafe
之前使用std::mem::MaybeUninit
and read the Rust nomicon。
正如 Optimistic Peach 所说,这主要是 Rust 的工作方式。一切都需要在 Rust 中初始化。其他变量也一样。
但 Rust 这样做的原因并不是编译器的问题。正如您从 C 中了解到的那样,那里的编译器可以毫无问题地编译代码,即使变量没有被初始化。问题是,如果您只是定义一个变量而不对其进行初始化,则可以访问该变量,并且该值将是该变量存储的内存位置中已经存在的任何值。
Rust 试图成为一种非常安全的语言。访问未初始化的内存通常是导致错误的原因,因此它确实希望防止这种情况发生。当程序代码中没有给出默认值时,设计者可以选择使用一些默认值,但他们决定始终需要明确的默认值。-这或多或少只是他们所做的设计选择。
可能选择这种设计的原因是在 Rust 中有几种类型,没有明显的默认值。在 C# 等其他语言中,您可以将 null
值分配给所有引用。在 Rust 中,您可以通过使用 Option<T>
作为类型(而不仅仅是 T)并分配 None
值来获得类似于 null
的东西。但这只有在程序员决定使用 Option<T>
而不是 T
时才有效。如果 Rust 中没有 null
并且程序员没有定义初始值,std::fs::File
类型变量的默认值可能是多少?
在 C 中,我可以使用尚未初始化的结构。我在 Rust 中尝试了这段代码:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main(){
let mut user1: User;
user1.active = false;
}
但它产生了一个编译错误:
error[E0381]: assign to part of possibly-uninitialized variable: `user1`
--> src/main.rs:10:5
|
10 | user1.active = false;
| ^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `user1`
为什么这在 C 中是允许的,但在 Rust 中是错误的?
All 值,它们必须具有初始化值。
这是因为使用未初始化值的操作具有未定义的行为。这可能会导致编译器意外地错误编译您的代码。
避免错误编译是 Rust 的主要目标之一;包括其他形式的未定义行为,例如数据竞争、取消引用无效指针或更改其他代码假定不会更改的数据。阅读更多 here。
在 C 中,您可以访问这些值;从而允许编译器在您违反合同后错误编译您的代码。然而,在 Rust 中,你不能这样做。
在某些语言中,例如 C#,您可以用 null
替换未初始化的值。我们有一个类似的概念:Option
s,要么是Some(value)
,要么有None
。
请注意,如果编译器由于与不合理操作相关的未定义行为而错误编译您的代码,这不是编译器的错。它也不是要寻找这个;它只是在尝试优化您的代码。如果我给你一根棒球棒,你用它打你的头,那么你就是在滥用它,作为设计师,这不是我的错,因为我无法预见你会滥用它。
有 种方法可以完成您可以在 C 中完成的工作。这些是 unsafe
并且强烈建议不要进行常规操作,因此请在跳入不必要的 unsafe
和可能不合理的行为之前尽最大努力寻找其他解决方案。
在涉足unsafe
之前使用std::mem::MaybeUninit
and read the Rust nomicon。
正如 Optimistic Peach 所说,这主要是 Rust 的工作方式。一切都需要在 Rust 中初始化。其他变量也一样。
但 Rust 这样做的原因并不是编译器的问题。正如您从 C 中了解到的那样,那里的编译器可以毫无问题地编译代码,即使变量没有被初始化。问题是,如果您只是定义一个变量而不对其进行初始化,则可以访问该变量,并且该值将是该变量存储的内存位置中已经存在的任何值。
Rust 试图成为一种非常安全的语言。访问未初始化的内存通常是导致错误的原因,因此它确实希望防止这种情况发生。当程序代码中没有给出默认值时,设计者可以选择使用一些默认值,但他们决定始终需要明确的默认值。-这或多或少只是他们所做的设计选择。
可能选择这种设计的原因是在 Rust 中有几种类型,没有明显的默认值。在 C# 等其他语言中,您可以将 null
值分配给所有引用。在 Rust 中,您可以通过使用 Option<T>
作为类型(而不仅仅是 T)并分配 None
值来获得类似于 null
的东西。但这只有在程序员决定使用 Option<T>
而不是 T
时才有效。如果 Rust 中没有 null
并且程序员没有定义初始值,std::fs::File
类型变量的默认值可能是多少?