Rust 中的类型

&str与String

&str代表不可变的字符切片&[u8]。
String是堆上的Vec,所以其本质是一个指针*const Vec<u8>。

&str => String

let str: String = "abc".to_string();
let str: String = String::from("abc");

String => &str

let str: &str = &*String::from("abc"); // 注意这里先解引用再取引用
let str: &str = String::from("abc").as_str(); // 不推荐,字符串是临时的,无法使用

字符与字符串

Rust使用UTF-8编码。对于ASCII或者其超集ISO-8859-1(Latin-1)字符,还可以使用r"[a-zA-Z]"来声明。

str.as_ptr();  // *const u8
str.as_bytes(); // &[u8]
str.as_bytes_mut(); // &mut [u8] 不安全
str.len(); // byte length
let chs: Vec<char>  = str.chars().collect(); // 获取字符数组
str.chars().nth(0); // 获取第n个char(一个char表示一个Unicode一个代码点)

字符串的比较和匹配

fn main() -> std::io::Result<()> {
    let str1: String = String::from("abc");
    let str2: String = String::from("abc");

    println!("equals? {}", str1.eq(&str2)); // 比较
    println!("equals? {}", str1 == str2); // 可直接==比较

    match str1.as_str() { // 匹配最好转为字符切片
        "abc" => {
            println!("abc");
        }
        _ => {}
    }
    Ok(())
}

指针

引用其实可以转换为指针:

fn main() -> std::io::Result<()> {
    let a = 8;
    let b = &a as *const i32 as *mut i32;
    unsafe {
        *b = 99;
    }
    println!("a = {0}", a); // 99
    Ok(())
}

关于字符切片:

// 引用强转指针
fn main() -> std::io::Result<()> {
    let a: &str = "this is a &[str]"; // a虽然是一个引用,其实是一个指向str切片的指针变量
    let p0: *const str = a as *const str; // a强转为常指针,得到str的起始地址
    let p1: *const *const str = &a as *const &str as *const *const str; // 取a变量的引用,先强转为指向&str的常指针,再强转为指向str切片指针的指针
    // error:
    // let p1: *const *const str = &a as *const *const str; // 不可一步转完
    println!("{:p} {:p} {:p}", p0, p1, &a); // 后二者相等
    let p2: *const str = &a[..2][..][..];
    println!("{:p}", p2);
    // 指针失去了切片的长度记忆能力
    // println!("{}", p2); // 无法编译
    let pr: &str = &a[..2][..][..];
    println!("{}", pr); // 正常打印字符切片
    Ok(())
}

/*
0x7ff7f02ef3e8 0x49a5fcf990 0x49a5fcf990
0x7ff7f02ef3e8
th
*/

size_of

    println!("{}", std::mem::size_of::<*const i8>());

END

posted @ 2021-04-27 23:13  develon  阅读(171)  评论(0编辑  收藏  举报