- Stack vs Heap(栈内存 vs 堆内存)
Stack(后进先出,LIFO)
Stack上的数据必须拥有已知的固定的大小
大小未知的数据或运行时大小可能发生变化的数据必须存放在heap上
- String类型
//创建String类型的值
使用from函数
let s = String::from("hello"); 这类字符串可以被修改
fn main(){
let mut s = String::from("hello");
s.push_str(", world");
println!("{}", s);//hello, world
}
Rust语言中处理String类型的数据时为了避免二次释放的问题,被赋值的String参数就消失了(一份数据只能有一个拥有者)
举例:
fn main(){
let a = String::from("hello");
let b = a;
println!("{}", b);//hello
println!("{}", a);//报错因为a已经被释放
}
这种方式被称为:移动(Move)
- 引用和借用
举例:
fn main(){
let str = String::from("hello");
let new = &str;//&允许引用某些值而不取得其所有权
println!("{}, {}", new, str);
}
若不加&那么str就会被移动从而消失,加&就不取得所有权从而保留str,new和str都可以输出。
*为解引用
借用:
把引用作为函数参数的行为
(String类型中)不可以同时拥有可变和不可变引用,但是可以有多个不可变引用(例子)
fn main(){
let mut str = String::from("hello");
let ptr1 = &str;
let ptr2 = &str;
let s1 = &mut str;//报错
println!("{}, {}, {}", ptr1, ptr2, s1);
}
fn main(){
let mut str = String::from("hello");
let ptr1 = &str;
let ptr2 = &str;
let s1 = &str;
println!("{}, {}, {}", ptr1, ptr2, s1);
}
-
切片
一道题,编写一个函数:
它接受字符串作为参数
返回它在这个字符串里找到的第一个单词
如果函数没找到任何空格,那么整个字符串就被返回
- 使用字符串切片来解决
字符串切片是指向字符串中一部分内容的引用
let s = String::from("Hello world");
let hello = &s[0..5];
let world = &s[6..11];
fn main(){
let s = String::from("Hello world");
let wordindex = first_word(&s);
let word = &s[0..wordindex];//[..wordindex]也可以
println!("{}", word);
}
fn first_word(s:&String)->usize{
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item==b' ' //b'*'为byte对象的意思
{
return i;//return即为终止函数的运行
}
}
s.len()
}
进阶版-->函数返回一个字符串切片
fn main(){
let s = String::from("Hello world");
let word = first_word(&s);
println!("{}", word);
}
fn first_word(s:&String)->&str{//&str字符串切片类型
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item==b' ' //b'*'为byte对象的意思
{
return &s[..i];//return即为终止函数的运行
}
}
&s[..]
}
再进行完善-->有经验的程序员一般用字符串切片代替字符串引用作为参数
注意:let str = "xzc";其中str就是&str类型(字符串切片类型)
fn main(){
//let s = String::from("Hello world");
//let word = first_word(&s[..]);
let s = "Hello world";//s就是字符串切片类型
let word = first_word(s);
println!("{}", word);
}
fn first_word(s:&str)->&str{//&str字符串切片类型
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item==b' ' //b'*'为byte对象的意思
{
return &s[..i];//return即为终止函数的运行
}
}
&s[..]
}
其他类型切片
fn main(){
let a = [1, 2, 3, 4, 5];
let slice = &a[..3];//1 2 3
}