为什么Rust有String和str?String和str之间有什么区别?什么时候使用String而不是str,反之亦然?其中一个被弃用了吗?
当前回答
一些用法
示例1.rs
fn main(){
let hello = String::("hello");
let any_char = hello[0];//error
}
示例_2.rs
fn main(){
let hello = String::("hello");
for c in hello.chars() {
println!("{}",c);
}
}
示例_3.rs
fn main(){
let hello = String::("String are cool");
let any_char = &hello[5..6]; // = let any_char: &str = &hello[5..6];
println!("{:?}",any_char);
}
阴影
fn main() {
let s: &str = "hello"; // &str
let s: String = s.to_uppercase(); // String
println!("{}", s) // HELLO
}
作用
fn say_hello(to_whom: &str) { //type coercion
println!("Hey {}!", to_whom)
}
fn main(){
let string_slice: &'static str = "you";
let string: String = string_slice.into(); // &str => String
say_hello(string_slice);
say_hello(&string);// &String
}
连接两个字符串
// String is at heap, and can be increase or decrease in its size
// The size of &str is fixed.
fn main(){
let a = "Foo";
let b = "Bar";
let c = a + b; //error
// let c = a.to_string + b;
}
请注意,String和&str是不同的类型,在99%的时间里,您只需要关心&str。
其他回答
这里有一个简单快捷的解释。
字符串-可增长的、可拥有的堆分配数据结构。它可以强制为&str。
str是(现在,随着Rust的发展)可变的固定长度字符串,存在于堆或二进制文件中。只能通过字符串切片视图(如&str)将str作为借用类型进行交互。
使用注意事项:
如果您想拥有或变异字符串,请首选字符串,例如将字符串传递给另一个线程等。
如果希望字符串的只读视图,请首选&str。
str,仅用作&str,是一个字符串片段,是对UTF-8字节数组的引用。
字符串过去是~str,一个可增长的、拥有的UTF-8字节数组。
对于C#和Java用户:
Rust‘String==StringBuilderRust的&str==(不可变)字符串
我喜欢将&str视为字符串的视图,就像Java/C#中的一个内部字符串,您不能更改它,只能创建一个新字符串。
锈蚀和字符串(&S)
字符串:
Rust拥有String类型,字符串本身存在于堆中,因此是可变的,可以更改其大小和内容。因为当拥有字符串的变量超出范围时,String是被拥有的,所以堆上的内存将被释放。String类型的变量是胖指针(指针+相关元数据)fat指针长度为3*8字节(字大小),由以下3个元素组成:指向堆上实际数据的指针,它指向第一个字符字符串长度(字符数)堆上字符串的容量
&字符串:
Rust非拥有的String类型,默认情况下是不可变的。字符串本身位于内存中的其他位置,通常位于堆或“静态内存”中。因为当&str变量超出范围时,字符串是非所有的,所以字符串的内存不会被释放。&str类型的变量是胖指针(指针+相关元数据)fat指针长度为2*8字节(字大小),由以下2个元素组成:指向堆上实际数据的指针,它指向第一个字符字符串长度(字符数)
例子:
use std::mem;
fn main() {
// on 64 bit architecture:
println!("{}", mem::size_of::<&str>()); // 16
println!("{}", mem::size_of::<String>()); // 24
let string1: &'static str = "abc";
// string will point to `static memory which lives through the whole program
let ptr = string1.as_ptr();
let len = string1.len();
println!("{}, {}", unsafe { *ptr as char }, len); // a, 3
// len is 3 characters long so 3
// pointer to the first character points to letter a
{
let mut string2: String = "def".to_string();
let ptr = string2.as_ptr();
let len = string2.len();
let capacity = string2.capacity();
println!("{}, {}, {}", unsafe { *ptr as char }, len, capacity); // d, 3, 3
// pointer to the first character points to letter d
// len is 3 characters long so 3
// string has now 3 bytes of space on the heap
string2.push_str("ghijk"); // we can mutate String type, capacity and length will aslo change
println!("{}, {}", string2, string2.capacity()); // defghijk, 8
} // memory of string2 on the heap will be freed here because owner goes out of scope
}
一些用法
示例1.rs
fn main(){
let hello = String::("hello");
let any_char = hello[0];//error
}
示例_2.rs
fn main(){
let hello = String::("hello");
for c in hello.chars() {
println!("{}",c);
}
}
示例_3.rs
fn main(){
let hello = String::("String are cool");
let any_char = &hello[5..6]; // = let any_char: &str = &hello[5..6];
println!("{:?}",any_char);
}
阴影
fn main() {
let s: &str = "hello"; // &str
let s: String = s.to_uppercase(); // String
println!("{}", s) // HELLO
}
作用
fn say_hello(to_whom: &str) { //type coercion
println!("Hey {}!", to_whom)
}
fn main(){
let string_slice: &'static str = "you";
let string: String = string_slice.into(); // &str => String
say_hello(string_slice);
say_hello(&string);// &String
}
连接两个字符串
// String is at heap, and can be increase or decrease in its size
// The size of &str is fixed.
fn main(){
let a = "Foo";
let b = "Bar";
let c = a + b; //error
// let c = a.to_string + b;
}
请注意,String和&str是不同的类型,在99%的时间里,您只需要关心&str。
推荐文章
- 如何删除表中特定列的第一个字符?
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- 将整数转换为字符串,以逗号表示千
- 将JavaScript字符串中的多个空格替换为单个空格
- printf()和puts()在C语言中的区别是什么?
- jQuery -替换字符串中某个字符的所有实例
- Base64长度计算?
- 使用split("|")按管道符号拆分Java字符串
- Std::cin输入空格?
- Rust中的默认函数参数
- 我如何在c++中创建一个随机的字母数字字符串?
- 如何使用JavaScript大写字符串中每个单词的第一个字母?
- Java中的split()方法对点(.)不起作用。
- 我如何检查如果一个变量是JavaScript字符串?
- 如何显示有两个小数点后的浮点数?