Rust语言——所有权

  • 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
}

上一篇:风尚云网-JS相关综合面试题(不看后悔系列)持续更新...


下一篇:移动零(JS)