Rust官方的解释:
“String 是一个被拥有(owned)的在堆上分配的 UTF-8 的字节缓冲区。可变 String 可以被修改,根据需要增加其容量。
&str 是一个指向分配在某处的 String 的一个固定容量的「视图」。如果切片是在从 String 解引而来的,则通常是指向在堆上,如果是字符串字面值,则指向静态内存。
&str 是一个由 Rust 语言实现的原生类型,而 String 则是由标准库实现的。”
对于Rust而言,“字符串”是 Unicode 标量值的序列编码为 utf - 8 字节的流。所有字符串都必须保证为有效的 utf-8 编码序列。
但,不止这些,Rust关于字符串的处理有些个性。
let a ="hello world";
let b ="ok!";
1、字面的“字符串”是&str
a、b都是&str,不是String.
对Rust而言,&str更象一个固定的数组;String更象一个可变的数组;
2、实现&str =>String的转换
let c =a.to_string(); //方法一
let d =String::from(b) //方法二
或let d =a.to_owned();
3、实现String =>&str 的转换: 加一个&
let e = &String::from("hello world");
或 使用as_str();
let e_0 = String::from("hello world");
let e = e_0.as_str();
但:不可以直接
let e =String::from("hello world").as_str();
4、一个String+一个&str =>String
注意,首要的要是String,后面可以接N个&str.
let f = c+b;
或let f =c+b+e;//增加一个也可以
let g = c.clone()+b+e
当然,另外的方法是:push_str()
let mut strs = "hello".to_string();
strs.push_str(" world!"); // hello world!
println!("state1 :{:?}", strs);
let mut s = String::from("foo");
s.push_str("bar"); //foobar
println!("{:?}", s);
5、两个或多个String 如何变成一个String?
let h = c +&d; //
如果要多个,比如:
let h =c +&d +&String::from("great!");
或
let i = c.clone()+ &d;//意义不大
或
let j = format!("{0}{1}", a, b);
6、比如,一个f32,一个String,要变成新的String,
let num =2008_u32;
let mystr =String::from(" ,happy new year!");
let num_str = format!("{0}{1}", num, mystr);//2008 ,happy new year!
推荐这种方式,比较方便,灵活性也比较强。其它方式也可以。
let num1 =200_u32;
let num2 =8_u32;
let mystr2 ="f32"
let new_num_str =format!("{0}{1}_{2}",num1,num2,mystr2);//2008_f32
7、关于as_bytes(); chars();
这里想提醒一下的是,字符和byte并不是简单一一对应的。
let love_china = "忠犬ハチ公";
for (num, bt) in love_china.as_bytes().iter().enumerate() {
println!("length:{:?} num:{:?} byte:{:?}", love_china.len(), num, bt);
}
for (num, ch) in love_china.chars().enumerate() {
println!("length:{:?} num:{:?} char:{:?}", love_china.len(), num, ch);
}
8、slice, []
&str,String都不能直接进行slice.
let mystr:&str = "abcd";
let my_str:String = "ABCD".to_string();
//println!("mystr :{:?}", mystr[1..]); =>error
println!("mystr :{:?}", &mystr[1..2]); //"bc"
println!("mystr :{:?}", &mystr[1..]); //"bcd"
println!("mystr :{:?}", &mystr[..]); // "abcd"
//很显然,String不能直接进行slice
//println!("my_str :{:?}", my_str[1..]); =>error
println!("my_str :{:?}", &my_str[1..2]); //"BC"
println!("my_str :{:?}", &my_str[1..]); //"BCD"
println!("my_str :{:?}", &my_str[..]); //"ABCD"
9、关于&str内部的地址
let mystr :&str = "abcd";
println!("mystr address: {:p}", &mystr[1..]);//从第2个开始
println!("mystr address: {:p}", &mystr[2..]);
println!("mystr address: {:p}", &mystr[3..]);
output:
mystr address: 0x7ff6ffcd0612
mystr address: 0x7ff6ffcd0613
mystr address: 0x7ff6ffcd0614
大家发现什么?
10、extend: String聚合 char
let mut message = String::from("The first three letters are: ");
message.extend(&['a', 'b', 'c']);
println!("message:{:?}", message);//message:"The first three letters are: abc"
11、String的内存分布
let s1 =String::from("hello");