let r;
{
r = String::new("foobar");
}
println!("{}", r);
let x;
println!("{}", x = 3); // wat
println!("{x} {y} {z}", x = 3, z = 1, y = 2);
rustup update
let a: [i32; 5] = [1, 2, 3, 4, 5];
let elem = a[2];
println!("{}", elem); // 3
[T; n]
[T; 3]
и [T; 5]
са различни
let a: [[i32; 5]; 3] = [
[01, 02, 03, 04, 05],
[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25],
];
let elem_1_2 = a[1][2];
println!("{}", elem_1_2); // ?
// ако работи - добре
let a = [1, 2, 3, 4, 5];
// ако не - трябва да кажем типа на поне един елемент
let a = [1_i32, 2, 3, 4, 5];
let a = [1, 2, 3_i32, 4, 5];
let a = [1, 2, 3, 4, 5_i32];
let a = [
[01, 02, 03, 04, 05],
[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25_i32],
];
let a = vec![1, 2, 3, 4, 5];
let elem = a[2];
println!("{}", elem); // 3
Vec<T>
vec!
позволява лесно инициализиране
let a = vec![1, 2, 3, 4, 5];
Еквивалентно на
let a = {
let mut tmp = Vec::new();
tmp.push_back(1);
tmp.push_back(2);
tmp.push_back(3);
tmp.push_back(4);
tmp.push_back(5);
tmp
};
let v = vec![String::from("баба"), String::from("дядо")];
let baba = v[0]; // грешка, String не е Copy
let v = vec![String::from("баба"), String::from("дядо")];
let baba = &v[0];
let dqdo = &v[1];
// let vnuche = &v[2]; // грешка при изпълнение
let v = vec![String::from("баба"), String::from("дядо")];
let baba = &v[0];
let dqdo = &v[1];
v.push_back(String::from("внуче")); // грешка
Можем да заемаме отделни части от структури и кортежи
let x = (1, 2);
let r1 = &x;
let r2 = &x.0;
let r3 = &x.1;
Отделните части се считат като отделни стойности от borrow checker-a
let mut x = (1, 2);
let r1 = &mut x.0;
let r2 = &mut x.1;
let r1 = &mut x.0;
let r2 = &mut x.0; // грешка
Но се считат и като заемане на цялата структура
let mut x = (1, 2);
let r1 = &x.0;
let r2 = &mut x; // грешка
let r1 = &mut x.0;
let r2 = &x // грешка
let mut a = [String::from("баба"), String::from("дядо")];
let baba = &mut a[0];
let dqdo = &mut a[1]; // ?
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
println!("{} {}", hello, world);
&[T]
, за резен от масив
&str
, за резен от низlet s = String::from("hello");
let len = s.len();
let slice = &s[0..2];
let slice = &s[..2];
let slice = &s[3..len];
let slice = &s[3..];
let slice = &s[..];
fn first_word(s: &String) -> &str {
let mut i = 0;
for byte in s.bytes() {
if byte == b' ' {
return &s[0..i];
}
i += 1;
}
&s[..]
}
Какво става, ако не е псевдоним?
let s = String::from("hello world");
let hello = s[0..5];
println!("{}", hello);
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied --> src/main.rs:3:9 | 3 | let hello = s[0..5]; | ^^^^^ `str` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `str` = note: all local variables must have a statically known size
fn first_word(s: &String) -> &str { /* ... */ }
fn first_word(s: &str) -> &str { /* ... */ }
fn main() {
let hello = String::from("hello world");
let word = first_word(&hello[..]); // slice от String
let hello = "hello world";
let word = first_word(&hello[..]); // slice от &str
let word = first_word(hello); // директно подаваме &str
}
Правила за автоматично конвертиране от един тип псевдоним до друг
Използват се само при:
Примери
&[u32; 5]
-> &[u32]
&Vec<u32>
-> &[u32]
&String
-> &str
fn main() {
let hello = String::from("hello world");
let word = first_word(&hello); // еквивалентно на &hello[..]
let len = hello.len(); // автоматично конвентира до &str и извиква метода му len
let hello = "hello world";
let word = first_word(hello); // директно подаваме &str
let len = hello.len(); // директно извикваме метода len
}
let s: &'static str = "Hello, world!";
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let baba = User {
email: String::from("baba@abv.bg"),
username: String::from("baba_1337"),
active: true,
sign_in_count: 1,
};
println!("{:?}", baba); // грешка, за момента
}
#[derive(Debug)]
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let baba = User {
email: String::from("baba@abv.bg"),
username: String::from("baba_1337"),
active: true,
sign_in_count: 1,
};
println!("{:?}", baba);
// => User { username: "baba_1337", email: "baba@abv.bg", sign_in_count: 1, active: true }
}
let baba = User { /* ... */ };
// baba.email = String::from("hackerman@l33t.hax"); // грешка
let mut baba = baba;
baba.email = String::from("hackerman@l33t.hax");
let hackerman = User {
email: String::from("hackerman@l33t.hax"),
username: String::from(""),
active: baba.active,
sign_in_count: baba.sign_in_count,
};
println!("{:?}", hackerman);
// => User { username: "", email: "hackerman@l33t.hax", sign_in_count: 1, active: true }
let hackerman = User {
email: String::from("hackerman@l33t.hax"),
username: String::from(""),
..baba,
};
println!("{:?}", hackerman);
// => User { username: "", email: "hackerman@l33t.hax", sign_in_count: 1, active: true }
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
struct Electron {} // Празни скоби...
struct Proton; // ...или просто точка и запетая.
// Използвайте същата нотация когато инстанцирате структурата.
let x = Electron {};
let y = Proton;
// let z = Electron; // грешка
А защо не &str
вместо String
?
struct User {
username: &str, // ???
email: &str, // ???
sign_in_count: u64,
active: bool,
}
error[E0106]: missing lifetime specifier --> src/main.rs:3:20 | 3 | username: &str, | ^ expected lifetime parameter ...
... са неща, за които ще говорим после
Просто използвайте String
засега
#[derive(Debug)]
struct Rectangle {
length: u32,
width: u32,
}
fn main() {
let r = Rectangle { length: 50, width: 30 };
println!(
"Площта на правоъгълника е {}px²",
r.length * r.width
);
}
#[derive(Debug)]
struct Rectangle {
length: u32,
width: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.length * self.width
}
}
fn main() {
let r = Rectangle { length: 50, width: 30 };
println!(
"Площта на правоъгълника е {}px²",
r.area()
);
}
impl Rectangle {
fn area(self: &Rectangle) -> u32 {
self.length * self.width
}
}
impl SomeStructType {
fn method_borrows(&self) -> u32 { 42 }
fn method_borrows_mutably(&mut self) -> u32 { 42 }
fn method_takes_ownership(self) -> u32 { 42 }
}
// impl std::string::String {
fn push_str(&mut self, string: &str) {
let mut s = String::from("hello");
// let s2 = &mut s; // грешка
s.push_str(", world");
struct Point { x: f64, y: f64 };
impl Point {
fn distance(self: &Point, other: &Point) -> f64 {
// ...
}
}
p1.distance(&p2);
(&&&p1).distance(&&&&&&p2);
Rust | C | |
---|---|---|
(&instance).field | (*(&instance)).field | instance->field |
(&&&instance).field | (***(&&&instance)).field | (**(&&&instance))->field |
#[derive(Debug)]
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
impl User {
fn new(username: &str, email: &str) -> User {
User {
username: String::from(username),
email: String::from(email),
sign_in_count: 0,
active: false,
}
}
}
fn main() {
let gosho = User::new("~*-_Lo60-Go60_-*~", "go6enceto@abv.bg");
}
impl User {
fn new(username: String, email: String) -> User {
User {
username,
email,
sign_in_count: 0,
active: false,
}
}
}
impl SomeLongStructNameThatWeDontWantToRepeat {
fn new(username: String, email: String) -> Self {
Self {
username,
email
}
}
}
fn main() {
let r = Rectangle { length: 50, width: 30 };
let area = Rectangle::area(&r);
println!("Площта на правоъгълника е {}px²", area);
}