[Rust] Play around with Rust
Few intertesting things from Rust
- Option<T>: with
Some
,unwrap()
function todo()
: to skil compiler error for a whileunreachable()
: similar to Typescript, asserts never.- vec vs array
- String vs &str
- Struct, Impl
- traits
Option<T>, similar to Maybe, Either
In Rust, Option
is an enum that represents the possibility of a value being present (Some
) or absent (None
). The unwrap()
method is used to extract the value from a Some
variant or panic if the Option
is None
.
fn main() {
let maybe_number: Option<i32> = get_number();
// Using unwrap() to get the value from the Option
let number = maybe_number.unwrap();
println!("The number is: {}", number);
}
fn get_number() -> Option<i32> {
// Return Some(value) if you have a value to return
Some(42)
// Return None if there is no value to return
// None
}
Keep in mind that using unwrap()
can be risky since it will cause your program to panic if the Option
contains None
.
It's generally better to use pattern matching or methods like unwrap_or
, unwrap_or_default
, or map
to handle Option
in a more graceful way.
unwrap_or
: set default value if is None
fn main() {
let maybe_number: Option<i32> = get_number();
// Using unwrap_or() to get the value from the Option or use a default value
let number = maybe_number.unwrap_or(0);
println!("The number is: {}", number);
}
fn get_number() -> Option<i32> {
// Return Some(value) if you have a value to return
// Some(42)
// Return None if there is no value to return
None
}
unwrap_or_default: set a defualt value by impl
, #[derive(Debug)]
#[derive()]
is an attribute used to automatically generate certain trait implementations for a struct or enum. In the example provided, #[derive(Debug, Default)]
is used to automatically generate the implementations for the Debug
and Default
traits for the Person
struct
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
impl Default for Person {
fn default() -> Self {
Person {
name: String::from("John Doe"),
age: 18,
}
}
}
fn main() {
let maybe_person: Option<Person> = get_person();
// Using unwrap_or() to get the value from the Option or use a default value
let person = maybe_person.unwrap_or_default();
println!("The person is: {:?}", person); // The person is: Person { name: "John Doe", age: 18 }
}
fn get_person() -> Option<Person> {
None
}
todo & unreachable
fn only_evens(x: usize) -> bool {
if x % 2 == 1 {
unreachable!("this should never happen")
}
// without todo: `if` may be missing an `else` clause
todo!("TODO: come to this part later")
}
fn main() {
only_evens(10)
}
vec vs array
In Rust, arrays have a fixed size, so you can't change the size directly. However, you can use a Vec
(vector) instead to achieve a similar effect.
fn main() {
let foo = vec![1, 2, 3];
let foo = someMethod(foo);
}
fn someMethod(mut input: Vec<i32>) -> Vec<i32> {
// Modify the input vector as needed
input.push(4); // Adding 4 to the vector as an example
input
}
need to use mut
, otherwise, you cannot call .push()
.
String vs &str
String
is a mutable, heap-allocated string type that owns its memory, while &str
is an immutable reference to a string that doesn't own the memory it points to. Use String
when you need to modify or build a string dynamically, and use &str
when you need to pass a read-only reference to a string, such as in function parameters.
Creating string:
fn main() {
let s1 = String::from("Hello, world!"); // Creates a String
let s2: &str = "Hello, world!"; // Creates a string slice
println!("s1: {}", s1);
println!("s2: {}", s2);
}
Passing a `&str` to a function:
fn main() {
let name = String::from("Alice");
greet(&name); // Passing a string slice to the greet function
}
fn greet(name: &str) {
println!("Hello, {}!", name);
}
Modify a String:
fn main() {
let mut s = String::from("Hello");
s.push_str(", world!");
println!("s: {}", s);
}
Creating a string slice from a `String`
fn main() {
let s = String::from("Hello, world!");
let hello = &s[0..5]; // Creating a string slice from a String
println!("hello: {}", hello);
}
Trait, Impl, Struct
- Traits in Rust are used to define shared behavior across types. They can define methods, associated functions, and associated types.
- Rust uses nominal typing, so a type must explicitly implement a trait using the
impl Trait for Type
syntax. - Traits are similar to interfaces in other languages, but they also allow you to provide default method implementations.
trait Person {
fn name(&self) -> &str;
fn age(&self) -> u32;
fn greet(&self) {
println!("Hello, my name is {} and I 'm {} years old", self.name(), self.age());
}
}
struct Student {
name: String,
age: u32,
}
impl Person for Student {
fn name(&self) -> &str {
&self.name
}
fn age(&self) -> u32 {
self.age
}
}
fn main() {
let student = Student { name: String::from("Alice"), age: 20 };
student.greet();
}
In the provided example, name
is of type String
, which is a growable, heap-allocated string type. When you return a reference to the name
field using &self.name
, you are borrowing a reference to the String
without transferring ownership. This allows the name
field to remain owned by the original Student
struct while still providing read access to its content. The return type of the name
method is &str
, an immutable string slice, so returning a reference to a String
as &str
is appropriate.
On the other hand, age
is of type u32
, which is a simple, fixed-size, and copyable integer type. When you return self.age
, you are returning a copy of the age
field because u32
implements the Copy
trait. This means that returning self.age
does not affect the ownership or borrowing of the age
field. The return type of the age
method is u32
, which matches the type of the age
field, so returning self.age
directly is appropriate.
In summary, you use &self.name
to return a reference to the String
as an immutable string slice (&str
), and you use self.age
to return a copy of the u32
value.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-05-09 [TypeScript] AssertType
2020-05-09 [Compose] Ex. FP-Box Chain
2019-05-09 [Functional Programming] De Morgan's Laws
2017-05-09 [Angular] Using NO_ERRORS_SCHEMA
2017-05-09 [Angular] Test Container component with async provider
2017-05-09 [Angular] Test component template
2016-05-09 [CSS3] Text ellipsis