学习Rust,官方文档全英文,查询不太方便,索性直接翻译完,方便查询使用。有需要自由转载,本人英文水平有限,文档是在谷歌翻译的基础上加个人理解完成,不敢保证正确。文档翻译错误的地方欢迎指出;
原文地址:https://doc.rust-lang.org/stable/std/string/struct.String.html
同时makedown文档(String.md)上传至码云平台https://gitee.com/z33/rustTest.git
Struct std::string::String
pub struct String { /* fields omitted */ }
UTF-8编码的可变长度字符串
String类型是对字符串内容拥有所有权的最常见的字符串类型。 它与其借用的对等体str有着密切的关系。
例:
使用String::from从文字字符串创建新的String
let hello = String::from("Hello, world!");
使用push新增一个字符(char)或者使用push_str新增一个&str
let mut hello = String::from("Hello, "); hello.push('w'); hello.push_str("orld!");
使用from_utf8将UTF-8类型的vector转换为String
// some bytes, in a vector let sparkle_heart = vec![240, 159, 146, 150]; // We know these bytes are valid, so we'll use `unwrap()`. let sparkle_heart = String::from_utf8(sparkle_heart).unwrap(); assert_eq!("💖", sparkle_heart);
UTF-8
String必须使用UTF-8,如果一定要是用非UTF-8编码,请使用OsString;同时,String无法使用索引引用:
let s = "hello"; println!("The first letter of s is {}", s[0]); // ERROR!!!
索引的目的是恒定时间操作(constant-time operation),但是UTF-8编码不允许,因为无法确定字符的长度,使用索引不清楚索引应返回哪种类型:字节,代码点还是字素簇。使用bytes和chars方法进行迭代。
解引用(Deref)
Strings实现了Deref<Target=str>,因此继承了所有str的方法。可以使用与&将字符串传递给采用&str的函数:
fn takes_str(s: &str) { } let s = String::from("Hello"); takes_str(&s);
这将根据String创建一个&str并将其传递。这种转换开销很低,因此通常函数会使用&strs作为参数,除非出于某些特定原因需要使用String。
在某些情况下,Rust没有足够的信息来进行这种转换,称为Deref强制转换。 在以下示例中,字符串slice&'a str实现了特征TraitExample,而函数example_func则采用了实现该特征的任何东西。 在这种情况下,Rust需要进行两次隐式转换,Rust没有办法进行转换。 因此,以下示例将无法编译。
原文:In certain cases Rust doesn't have enough information to make this conversion, known as Deref coercion. In the following example a string slice &'a str implements the trait TraitExample, and the function example_func takes anything that implements the trait. In this case Rust would need to make two implicit conversions, which Rust doesn't have the means to do. For that reason, the following example will not compile.
trait TraitExample {} impl<'a> TraitExample for &'a str {} fn example_func<A: TraitExample>(example_arg: A) {} fn main() { let example_string = String::from("example_string"); example_func(&example_string); }
有两种选择可以代替。 第一种是更改example_func(&example_string)为example_func(example_string.as_str()),使用方法as_str()显式提取包含字符串的字符串片段。 第二种方式更改example_func(&example_string)为example_func(&* example_string)。 在这种情况下,我们先将String引用到str,然后再将str引用回到&str。 第二种方法更常用,但是两种方法都可以显式地进行转换,而不是依赖隐式转换。
字符串由三个部分组成:指向某些字节的指针,长度和容量。 指针指向String用于存储其数据的内部缓冲区。 长度是当前存储在缓冲区中的字节数,容量是缓冲区的大小(以字节为单位)。 这样,长度将始终小于或等于容量。
此缓冲区始终存储在堆中。
使用as_ptr,len和Capacity方法查看:
use std::mem; let story = String::from("Once upon a time..."); let ptr = story.as_ptr(); let len = story.len(); let capacity = story.capacity(); // story has nineteen bytes assert_eq!(19, len); // Now that we have our parts, we throw the story away. mem::forget(story); // We can re-build a String out of ptr, len, and capacity. This is all // unsafe because we are responsible for making sure the components are // valid: let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ; assert_eq!(String::from("Once upon a time..."), s);
如果字符串具有足够的空间,向其添加元素将不会重新分配。 如下:
let mut s = String::new(); println!("{}", s.capacity()); for _ in 0..5 { s.push_str("hello"); println!("{}", s.capacity()); }
输出:
0 5 10 20 20 40
最初,我们没有分配内存,当我们追加字符时,它会适当地增加其容量。 如果我们改为使用with_capacity方法初始分配容量:
let mut s = String::with_capacity(25); println!("{}", s.capacity()); for _ in 0..5 { s.push_str("hello"); println!("{}", s.capacity()); }
输出:
25 25 25 25 25 25
这样的话,不需要循环分配更多的内存
方法
impl String
pub const fn new() -> String
创建一个新的空String
String为空,不会分配任何初始缓冲区。 虽然初始操作开销很小,但以后添加数据时可能会分配过多的分配。 如果清楚String需要容纳的数据大小,使用with_capacity方法更好。
使用
let s = String::new();
pub fn with_capacity(capacity: usize) -> String
创建一个特定容量的空String
字符串具有内部缓冲区来保存其数据。 容量是该缓冲区的长度,可以使用容量方法查询。 此方法创建带有一个初始缓冲区,可以容纳容量字节的空字符串,减少追加数据时重新分配缓冲区大小的次数。
如果给定容量为0,则不会进行分配,并且此方法与new()方法相同。
使用
let mut s = String::with_capacity(10); // The String contains no chars, even though it has capacity for more assert_eq!(s.len(), 0); // These are all done without reallocating... let cap = s.capacity(); for _ in 0..10 { s.push('a'); } assert_eq!(s.capacity(), cap); // ...but this may make the vector reallocate s.push('a');
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>
将bytes vector转换为String
字符串切片(&str)由字节(u8)组成,字节向量(Vec
)由字节组成,因此此函数在两者之间进行转换。 并非所有的字节片都是有效的字符串,但是:字符串要求它是有效的UTF-8。 from_utf8()检查以确保字节有效的UTF-8,然后进行转换。
如果您确定字节片是有效的UTF-8,并且不想引起有效性检查的开销,则此函数有一个不安全的版本from_utf8_unchecked,它具有相同的行为,但是会跳过检查。
为了提高效率,此方法不复制vector。
如果需要&str而不是String,请使用str::from_utf8。
与这个方法相反的方法是as_bytes.
如果切片不是UTF-8,则返回Err,并说明为什么提供的字节不是UTF-8。 已经移入的vector也包含在其中。
使用:
// some bytes, in a vector let sparkle_heart = vec![240, 159, 146, 150]; // We know these bytes are valid, so we'll use `unwrap()`. let sparkle_heart = String::from_utf8(sparkle_heart).unwrap(); assert_eq!("💖", sparkle_heart);
字节不正确:
// some invalid bytes, in a vector let sparkle_heart = vec![0, 159, 146, 150]; assert!(String::from_utf8(sparkle_heart).is_err());
有关此错误的详细信息,请参阅FromUtf8Error的文档。
pub fn from_utf8_lossy(v: &[u8]) -> Cow<str>
将字节切片转换为字符串,包括无效字符
字符串由字节(u8)组成,而字节片(&[u8])由字节组成,因此此函数在两者之间进行转换。 并非所有的字节片都是有效的字符串,但是:字符串必须是有效的UTF-8。 在此转换过程中,from_utf8_lossy()将用�替换任何无效的UTF-8字符
如果您确定字节片是有效的UTF-8,并且不想增加转换的开销,则此函数有一个不安全的版本from_utf8_unchecked,它具有相同的行为,但是会跳过检查。
此函数返回Cow <'a,str>。 如果我们的字节片无效的UTF-8,那么我们需要插入替换字符,这将改变字符串的大小,因此需要一个String。 但是,如果它已经是有效的UTF-8,则不需要新的分配。 这种返回类型使我们能够处理两种情况。
使用:
// some bytes, in a vector let sparkle_heart = vec![240, 159, 146, 150]; let sparkle_heart = String::from_utf8_lossy(&sparkle_heart); assert_eq!("💖", sparkle_heart);
字节不正确:
// some invalid bytes let input = b"Hello \xF0\x90\x80World"; let output = String::from_utf8_lossy(input); assert_eq!("Hello �World", output);
pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>
将 UTF-16编码的vector v解码为String,v含有任何无效字符时,返回Err
使用:
// 𝄞music let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0x0069, 0x0063]; assert_eq!(String::from("𝄞music"), String::from_utf16(v).unwrap()); // 𝄞mu<invalid>ic let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; assert!(String::from_utf16(v).is_err());
pub fn from_utf16_lossy(v: &[u16]) -> String
将 UTF-16编码的vector v解码为String,无效字符时使用�替代
与from_utf8_lossy返回Cow<'a, str>不同,from_utf16_lossy返回String,因为UTF-16转换为UTF-8需要分配内存
使用:
// 𝄞mus<invalid>ic<invalid> let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834]; assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"), String::from_utf16_lossy(v));
pub unsafe fn from_raw_parts( buf: *mut u8, length: usize, capacity: usize ) -> String
根据长度、容量和指针创建一个新的String
由于未检查的不变量数量,这非常不安全:
ptr处的内存需要事先由标准库使用的同一分配器分配。 长度必须小于或等于容量。 容量必须是正确的值。
违反这些规则可能会导致诸如破坏分配器的内部数据结构之类的问题。
有效地将ptr的所有权转移到String,然后可以随意分配,重新分配或更改指针所指向的内存内容。 调用此函数后,请确保没有其他人使用指针。
使用:
use std::mem; unsafe { let s = String::from("hello"); let ptr = s.as_ptr(); let len = s.len(); let capacity = s.capacity(); mem::forget(s); let s = String::from_raw_parts(ptr as *mut _, len, capacity); assert_eq!(String::from("hello"), s); }
pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String
将字节向量转换为字符串,而不检查字符串是否包含有效的UTF-8。
此函数不安全,因为它不检查传递给它的字节是否为有效的UTF-8。 如果违反了此约束,则将来的String用户可能会导致内存不安全问题,因为标准库的其余部分都假定String是有效的UTF-8。
使用:
// some bytes, in a vector let sparkle_heart = vec![240, 159, 146, 150]; let sparkle_heart = unsafe { String::from_utf8_unchecked(sparkle_heart) }; assert_eq!("💖", sparkle_heart);
pub fn into_bytes(self) -> Vec<u8>
将String转换为byte vector
不需要复制String的内容
使用:
let s = String::from("hello"); let bytes = s.into_bytes(); assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
pub fn as_str(&self) -> &str
提取整个String的字符串切片
使用:
let s = String::from("foo"); assert_eq!("foo", s.as_str());
pub fn as_mut_str(&mut self) -> &mut str
将String转换为可变字符串切片
使用:
let mut s = String::from("foobar"); let s_mut_str = s.as_mut_str(); s_mut_str.make_ascii_uppercase(); assert_eq!("FOOBAR", s_mut_str);
pub fn push_str(&mut self, string: &str)
将给定的字符串切片追加到String
使用:
let mut s = String::from("foo"); s.push_str("bar"); assert_eq!("foobar", s);
pub fn capacity(&self) -> usize
返回String的字节容量
使用:
let s = String::with_capacity(10); assert!(s.capacity() >= 10);
pub fn reserve(&mut self, additional: usize)
确保此字符串的容量至少比其长度大更多字节。
容量可能会增加比需要更多的字节,改方法用以防止频繁重新分配。
如果您不希望这种“至少”行为,可以使用reserve_exact方法。
需要防止新增容量大于unsize(原文:
Panics if the new capacity overflows usize.)
使用:
let mut s = String::new(); s.reserve(10); assert!(s.capacity() >= 10);
实际上可能不会增加容量:
let mut s = String::with_capacity(10); s.push('a'); s.push('b'); // s now has a length of 2 and a capacity of 10 assert_eq!(2, s.len()); assert_eq!(10, s.capacity()); // Since we already have an extra 8 capacity, calling this... s.reserve(8); // ... doesn't actually increase. assert_eq!(10, s.capacity());
pub fn reserve_exact(&mut self, additional: usize)
确保此字符串的容量至少比其长度大更多字节。
考虑使用reserve方法,除非您绝对比分配器更了解。
需要防止新增容量大于unsize(原文:
使用:
let mut s = String::new(); s.reserve_exact(10); assert!(s.capacity() >= 10);
实际上可能不会增加容量:
let mut s = String::with_capacity(10); s.push('a'); s.push('b'); // s now has a length of 2 and a capacity of 10 assert_eq!(2, s.len()); assert_eq!(10, s.capacity()); // Since we already have an extra 8 capacity, calling this... s.reserve_exact(8); // ... doesn't actually increase. assert_eq!(10, s.capacity());
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
这是仅nightly支持的实验性API。 (try_reserve#48043)
尝试为在给定String中至少插入更多元素保留容量。 该集合可以保留更多空间,以避免频繁的重新分配。 调用reserve之后,容量将大于或等于self.len()+增量(additional)。 如果容量已经足够,则不执行任何操作。
如果容量溢出,或者分配器报告失败,则返回错误。
使用:
#![feature(try_reserve)] use std::collections::TryReserveError; fn process_data(data: &str) -> Result<String, TryReserveError> { let mut output = String::new(); // Pre-reserve the memory, exiting if we can't output.try_reserve(data.len())?; // Now we know this can't OOM in the middle of our complex work output.push_str(data); Ok(output) }
pub fn try_reserve_exact( &mut self, additional: usize ) -> Result<(), TryReserveError>
这是仅nightly支持的实验性API。(try_reserve #48043)
尝试保留最小容量,以在给定的String中插入恰好更多的其他元素。 调用reserve_exact之后,容量将大于或等于self.len()+增量(additional)。 如果容量已经足够,则不执行任何操作。
请注意,分配器可能会给集合提供比其请求更多的空间。 因此,不能依靠容量来精确地最小化。 如果预计将来会插入,则优先保留。
如果容量溢出,或者分配器报告失败,则返回错误。
使用:
#![feature(try_reserve)] use std::collections::TryReserveError; fn process_data(data: &str) -> Result<String, TryReserveError> { let mut output = String::new(); // Pre-reserve the memory, exiting if we can't output.try_reserve(data.len())?; // Now we know this can't OOM in the middle of our complex work output.push_str(data); Ok(output) }
pub fn shrink_to_fit(&mut self)
缩小String的容量以使其长度匹配。
使用:
let mut s = String::from("foo"); s.reserve(100); assert!(s.capacity() >= 100); s.shrink_to_fit(); assert_eq!(3, s.capacity());
pub fn shrink_to(&mut self, min_capacity: usize)
这是仅nightly支持的实验性API。 (shrink_to #56431)
使用下限缩小此String的容量。
容量将至少保持与长度和提供的值一样大。(原文:The capacity will remain at least as large as both the length and the supplied value.)???
如果实际容量小于提供的最小容量,则发生 错误?(Panics)。
使用:
#![feature(shrink_to)] let mut s = String::from("foo"); s.reserve(100); assert!(s.capacity() >= 100); s.shrink_to(10); assert!(s.capacity() >= 10); s.shrink_to(0); assert!(s.capacity() >= 3);
pub fn push(&mut self, ch: char)
追加给定的字符(char)
使用:
let mut s = String::from("abc"); s.push('1'); s.push('2'); s.push('3'); assert_eq!("abc123", s);
pub fn as_bytes(&self) -> &[u8]
将String转换为byte数组( byte slice)
使用:
let s = String::from("hello"); assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
pub fn truncate(&mut self, new_len: usize)
将此字符串缩短为指定的长度。
如果new_len大于字符串的当前长度,则无效。
此方法对字符串的分配容量没有影响
如果new_len不位于char边界上则出错?(Panics)。
使用:
let mut s = String::from("hello"); s.truncate(2); assert_eq!("he", s);
pub fn pop(&mut self) -> Option<char>
移除末端的字符并返回,String为空时返回None
使用:
let mut s = String::from("foo"); assert_eq!(s.pop(), Some('o')); assert_eq!(s.pop(), Some('o')); assert_eq!(s.pop(), Some('f')); assert_eq!(s.pop(), None);
pub fn remove(&mut self, idx: usize) -> char
从指定位置删除一个字符并返回该字符
O(n)操作,需要复制缓冲区的每一个元素
idx越界时发生错误(Panics)
使用:
let mut s = String::from("foo"); assert_eq!(s.remove(0), 'f'); assert_eq!(s.remove(1), 'o'); assert_eq!(s.remove(0), 'o');
pub fn retain<F>(&mut self, f: F) where F: FnMut(char) -> bool,
仅保留谓词指定的字符。
换句话说,删除所有字符c,以使f(c)返回false。 此方法在原位运行,以原始顺序恰好一次访问每个字符,并保留保留字符的顺序。
使用:
let mut s = String::from("f_o_ob_ar"); s.retain(|c| c != '_'); assert_eq!(s, "foobar");
确切的顺序对于跟踪外部状态(例如索引)很有用。
let mut s = String::from("abcde"); let keep = [false, true, true, false, true]; let mut i = 0; s.retain(|_| (keep[i], i += 1).0); assert_eq!(s, "bce");
pub fn insert(&mut self, idx: usize, ch: char)
在String的指定字节位置插入一个字符。
O(n)操作,它需要复制缓冲区中的每个元素。
如果idx大于String的长度,或者它不位于char边界上,则发生错误。
使用:
let mut s = String::with_capacity(3); s.insert(0, 'f'); s.insert(1, 'o'); s.insert(2, 'o'); assert_eq!("foo", s);
pub fn insert_str(&mut self, idx: usize, string: &str)
1.16.0
在String的指定字节位置插入一个字符切片。
O(n)操作,它需要复制缓冲区中的每个元素。
如果idx大于String的长度,或者它不位于char边界上,则发生错误。
使用:
let mut s = String::from("bar"); s.insert_str(0, "foo"); assert_eq!("foobar", s);
pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8>
返回对该字符串内容的可变引用。
此函数不安全,因为它不检查传递给它的字节是否为有效的UTF-8。 如果违反了此约束,则将来的String用户可能会导致内存不安全问题,因为标准库的其余部分都假定String是有效的UTF-8。
使用:
let mut s = String::from("hello"); unsafe { let vec = s.as_mut_vec(); assert_eq!(&[104, 101, 108, 108, 111][..], &vec[..]); vec.reverse(); } assert_eq!(s, "olleh");
pub fn len(&self) -> usize
返回String的字节长度
使用:
let a = String::from("foo"); assert_eq!(a.len(), 3);
pub fn is_empty(&self) -> bool
判断String的长度是否为0
使用:
let mut v = String::new(); assert!(v.is_empty()); v.push('a'); assert!(!v.is_empty());
pub fn split_off(&mut self, at: usize) -> String
将字符串从指定索引位置分成两个
返回一个新分配的字符串。 self包含字节[0,at),返回的String包含字节[at,len)。 at必须在UTF-8代码点的边界上。
自身(self)的容量不会改变。
如果at不在UTF-8代码点边界上,或者超出字符串的最后一个代码点,则发生错误。
使用:
let mut hello = String::from("Hello, World!"); let world = hello.split_off(7); assert_eq!(hello, "Hello, "); assert_eq!(world, "World!");
pub fn clear(&mut self)
截断此字符串,删除所有内容。
String的长度为零,但容量不变。
使用:
let mut s = String::from("foo"); s.clear(); assert!(s.is_empty()); assert_eq!(0, s.len()); assert_eq!(3, s.capacity());
pub fn drain<R>(&mut self, range: R) -> Drain where R: RangeBounds<usize>,
创建一个迭代器,该迭代器删除String中的指定范围并返回已删除的字符。
注意:元素范围会被删除,即使直到最后迭代器未消耗。(原文:The element range is removed even if the iterator is not consumed until the end.)
如果起点或终点不在char边界上,或者它们超出范围,则发生错误。
使用:
let mut s = String::from("α is alpha, β is beta"); let beta_offset = s.find('β').unwrap_or(s.len()); // Remove the range up until the β from the string let t: String = s.drain(..beta_offset).collect(); println!("t:{},s:{}",t,s); assert_eq!(t, "α is alpha, "); assert_eq!(s, "β is beta"); // A full range clears the string s.drain(..); assert_eq!(s, "");
out:
t:α is alpha, ,s:β is beta
pub fn replace_range<R>(&mut self, range: R, replace_with: &str) where R: RangeBounds<usize>,
删除字符串中的指定范围,并将其替换为给定的字符串。 给定的字符串长度不必与范围相同。
如果起点或终点不在char边界上,或者它们超出范围,则发生错误。
使用:
let mut s = String::from("α is alpha, β is beta"); let beta_offset = s.find('β').unwrap_or(s.len()); // Replace the range up until the β from the string s.replace_range(..beta_offset, "Α is capital alpha; "); println!("s:{}",s); assert_eq!(s, "Α is capital alpha; β is beta");
Out:
s:Α is capital alpha; β is beta
pub fn into_boxed_str(self) -> Box<str>
将此字符串转换为Box
。
这将减少任何多余的容量。
使用:
let s = String::from("hello"); let b = s.into_boxed_str();
Deref <Target = str>中的方法
pub const fn len(&self) -> usize
返回自身的字节长度,可能不是人们认为字符串的长度。
使用:
let len = "foo".len(); assert_eq!(3, len); let len = "ƒoo".len(); // fancy f! assert_eq!(4, len); let mut l="哈哈哈".len(); println!("哈哈哈的长度是:{}",l); l="哈哈哈123ABC".len(); println!("哈哈哈123ABC的长度是:{}",l);
Out:
哈哈哈的长度是:9 哈哈哈123ABC的长度是:15
pub const fn is_empty(&self) -> bool
判断字符长度是否为0
使用:
let s = ""; assert!(s.is_empty()); let s = "not empty"; assert!(!s.is_empty());
pub fn is_char_boundary(&self, index: usize) -> bool
检查第index个字节位于UTF-8代码点序列的开头和/或结尾。
字符串的开始和结束(当index == self.len()时)被视为边界。
如果index大于self.len(),则返回false。
使用:
let s = "Löwe 老虎 Léopard"; assert!(s.is_char_boundary(0)); // start of `老` assert!(s.is_char_boundary(6)); assert!(s.is_char_boundary(s.len())); // second byte of `ö` assert!(!s.is_char_boundary(2)); // third byte of `老` assert!(!s.is_char_boundary(8));
pub const fn as_bytes(&self) -> &[u8]
将字符串切片(String slice)转换为字节切片(byte slice)。 要将字节片转换回字符串片,请使用str :: from_utf8函数。
使用:
let bytes = "bors".as_bytes(); assert_eq!(b"bors", bytes);
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8]
将可变字符串切片(String slice)转换为可变字节切片(byte slice)。 要将字节片转换回字符串片,请使用str :: from_utf8_mut函数。
使用:
let mut s = String::from("Hello"); let bytes = unsafe { s.as_bytes_mut() }; assert_eq!(b"Hello", bytes);
Mutability(可变性):
let mut s = String::from("🗻∈🌏"); unsafe { let bytes = s.as_bytes_mut(); bytes[0] = 0xF0; bytes[1] = 0x9F; bytes[2] = 0x8D; bytes[3] = 0x94; } assert_eq!("🍔∈🌏", s);
pub const fn as_ptr(&self) -> *const u8
将字符切片(string slice)转换为指针
指针将指向字符串切片的第一个字节。
调用者必须确保返回的指针永远不会被写入。 如果需要更改字符串切片的内容,请使用as_mut_ptr。
使用:
let s = "Hello"; let ptr = s.as_ptr();
pub fn as_mut_ptr(&mut self) -> *mut u8
将可变字符切片(mutable string slice)转换为指针
指针将指向字符串切片的第一个字节。
确保修改为有效的UTF-8
pub fn get<I>(&self, i: I) -> Option<&<I as SliceIndex<str>>::Output> where I: SliceIndex<str>,
返回str的子片段。
这是索引str的非紧急选择。 每当等效的索引操作将崩溃时,将返回None。
使用:
let v = String::from("🗻∈🌏"); assert_eq!(Some("🗻"), v.get(0..4)); // indices not on UTF-8 sequence boundaries assert!(v.get(1..).is_none()); assert!(v.get(..8).is_none()); // out of bounds assert!(v.get(..42).is_none());
pub fn get_mut<I>( &mut self, i: I ) -> Option<&mut <I as SliceIndex<str>>::Output> where I: SliceIndex<str>,
返回可变的str子片段。
这是索引str的非紧急选择。 每当等效的索引操作将崩溃时,将返回None。
使用:
let mut v = String::from("hello"); // correct length assert!(v.get_mut(0..5).is_some()); // out of bounds assert!(v.get_mut(..42).is_none()); assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v)); assert_eq!("hello", v); { let s = v.get_mut(0..2); let s = s.map(|s| { s.make_ascii_uppercase(); &*s }); assert_eq!(Some("HE"), s); } assert_eq!("HEllo", v);
pub unsafe fn get_unchecked<I>(&self, i: I) -> &<I as SliceIndex<str>>::Output where I: SliceIndex<str>,
返回未经检查的str子切片。这是索引str的未经检查的替代方法。
此函数的调用者有责任满足以下先决条件:
- 起始索引必须位于结束索引之前;
- 索引必须在原始切片的范围内;
- 索引必须位于UTF-8序列边界上。
失败: 返回的字符串片可能引用了无效的内存或违反了由str类型传达的不变式。
使用:
let v = "🗻∈🌏"; unsafe { assert_eq!("🗻", v.get_unchecked(0..4)); assert_eq!("∈", v.get_unchecked(4..7)); assert_eq!("🌏", v.get_unchecked(7..11)); }
pub unsafe fn get_unchecked_mut<I>( &mut self, i: I ) -> &mut <I as SliceIndex<str>>::Output where I: SliceIndex<str>,
返回未经检查的可变str子切片。这是索引str的未经检查的替代方法。
此函数的调用者有责任满足以下先决条件:
- 起始索引必须位于结束索引之前;
- 索引必须在原始切片的范围内;
- 索引必须位于UTF-8序列边界上。
失败: 返回的字符串片可能引用了无效的内存或违反了由str类型传达的不变式。
使用:
let mut v = String::from("🗻∈🌏"); unsafe { assert_eq!("🗻", v.get_unchecked_mut(0..4)); assert_eq!("∈", v.get_unchecked_mut(4..7)); assert_eq!("🌏", v.get_unchecked_mut(7..11)); }
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str
从1.29.0开始不推荐使用,使用get_unchecked(begin..end)替代
从另一个字符串切片创建一个字符串切片,绕过安全检查。
通常不建议这样做,请谨慎使用! 有关安全的选择,请参见str和Index。
这个新片段从开始到结束,包括开始但不包括结束。
slice_mut_unchecked方法获取可变的字符串切片。
函数的调用者有责任满足三个先决条件:
- 开始必须在结束之前。
- 开始和结束必须是字符串切片中的字节位置。
- 开始和结束必须位于UTF-8序列边界上。
使用:
let s = "Löwe 老虎 Léopard"; unsafe { assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21)); } let s = "Hello, world!"; unsafe { assert_eq!("world", s.slice_unchecked(7, 12)); }
pub unsafe fn slice_mut_unchecked( &mut self, begin: usize, end: usize ) -> &mut str
从1.29.0开始不推荐使用,使用get_unchecked_mut(begin..end)替代
从另一个字符串切片创建一个字符串切片,绕过安全检查。
通常不建议这样做,请谨慎使用! 有关安全的选择,请参见str和IndexMut。
这个新片段从开始到结束,包括开始但不包括结束。
slice_unchecked方法获取不变的字符串切片。
函数的调用者有责任满足三个先决条件:
- 开始必须在结束之前。
- 开始和结束必须是字符串切片中的字节位置。
开始和结束必须位于UTF-8序列边界上。
pub fn split_at(&self, mid: usize) -> (&str, &str)
在索引处将一个字符串切片分成两个。
参数mid应该是字符串开头的字节偏移量。 它也必须在UTF-8代码点的边界上。
返回的两个切片从字符串切片的开始到中间,再从字符串切片的中间到结尾。
要获取可变的字符串切片,请参见split_at_mut方法。
如果mid不在UTF-8代码点边界上,或者超出字符串片段的最后一个代码点,则发生错误。
使用:
let s = "Per Martin-Löf"; let (first, last) = s.split_at(3); assert_eq!("Per", first); assert_eq!(" Martin-Löf", last);
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str)
在索引处将一个可变字符串切片分成两个。
参数mid应该是字符串开头的字节偏移量。 它也必须在UTF-8代码点的边界上。
返回的两个切片从字符串切片的开始到中间,再从字符串切片的中间到结尾。
要获取不变的字符串切片,请参见split_at方法。
如果mid不在UTF-8代码点边界上,或者超出字符串片段的最后一个代码点,则发生错误。
使用:
let mut s = "Per Martin-Löf".to_string(); { let (first, last) = s.split_at_mut(3); first.make_ascii_uppercase(); assert_eq!("PER", first); assert_eq!(" Martin-Löf", last); } assert_eq!("PER Martin-Löf", s);
pub fn chars(&self) -> Chars
返回字符切片的字符(char)迭代器
由于字符串切片由有效的UTF-8组成,因此我们可以通过char遍历字符串切片。 此方法返回这样的迭代器。
重要的是要记住,char表示Unicode标量值,可能与您对“字符”的概念不符。 字素簇的迭代可能是您真正想要的。
使用:
let word = "goodbye"; let count = word.chars().count(); assert_eq!(7, count); let mut chars = word.chars(); assert_eq!(Some('g'), chars.next()); assert_eq!(Some('o'), chars.next()); assert_eq!(Some('o'), chars.next()); assert_eq!(Some('d'), chars.next()); assert_eq!(Some('b'), chars.next()); assert_eq!(Some('y'), chars.next()); assert_eq!(Some('e'), chars.next()); assert_eq!(None, chars.next());
注意,迭代的是字符(char)而不是字:
let y = "y̆"; let mut chars = y.chars(); assert_eq!(Some('y'), chars.next()); // not 'y̆' assert_eq!(Some('\u{0306}'), chars.next()); assert_eq!(None, chars.next());
pub fn char_indices(&self) -> CharIndices
在字符串切片的字符及其位置上返回一个迭代器。
由于字符串切片由有效的UTF-8组成,因此我们可以通过char遍历字符串切片。 此方法返回这两个字符及其字节位置的迭代器。
迭代器产生元组->(位置,字符)。
使用:
let word = "goodbye"; let count = word.char_indices().count(); assert_eq!(7, count); let mut char_indices = word.char_indices(); assert_eq!(Some((0, 'g')), char_indices.next()); assert_eq!(Some((1, 'o')), char_indices.next()); assert_eq!(Some((2, 'o')), char_indices.next()); assert_eq!(Some((3, 'd')), char_indices.next()); assert_eq!(Some((4, 'b')), char_indices.next()); assert_eq!(Some((5, 'y')), char_indices.next()); assert_eq!(Some((6, 'e')), char_indices.next()); assert_eq!(None, char_indices.next());
注意,迭代的是字符(char)而不是字:
let yes = "y̆es"; let mut char_indices = yes.char_indices(); assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆') assert_eq!(Some((1, '\u{0306}')), char_indices.next()); // note the 3 here - the last character took up two bytes assert_eq!(Some((3, 'e')), char_indices.next()); assert_eq!(Some((4, 's')), char_indices.next()); assert_eq!(None, char_indices.next());
pub fn bytes(&self) -> Bytes
字符串切片的字节(byte)迭代器。
由于字符串切片由字节序列组成,因此我们可以逐字节遍历字符串切片。 此方法返回这样的迭代器。
使用:
let mut bytes = "bors".bytes(); assert_eq!(Some(b'b'), bytes.next()); assert_eq!(Some(b'o'), bytes.next()); assert_eq!(Some(b'r'), bytes.next()); assert_eq!(Some(b's'), bytes.next()); assert_eq!(None, bytes.next());
pub fn split_whitespace(&self) -> SplitWhitespace
按空格(不可见字符)分割字符串切片
返回的迭代器将返回作为原始字符串切片的子切片的字符串切片,并以任意数量的空格分隔。
“空白”是根据Unicode派生核心属性White_Space的术语定义的。 如果只想在ASCII空格上分割,请使用split_ascii_whitespace。
使用:
let mut iter = "A few words".split_whitespace(); assert_eq!(Some("A"), iter.next()); assert_eq!(Some("few"), iter.next()); assert_eq!(Some("words"), iter.next()); assert_eq!(None, iter.next());
考虑到不同类型的空格:
let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace(); assert_eq!(Some("Mary"), iter.next()); assert_eq!(Some("had"), iter.next()); assert_eq!(Some("a"), iter.next()); assert_eq!(Some("little"), iter.next()); assert_eq!(Some("lamb"), iter.next()); assert_eq!(None, iter.next());
pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace
按ASCII空格(不可见字符)分割字符串切片。
返回的迭代器将返回作为原始字符串切片的子切片的字符串切片,并以任意数量的ASCII空格分隔。
要改为按Unicode空格分割,请使用split_whitespace。
使用:
let mut iter = "A few words".split_ascii_whitespace(); assert_eq!(Some("A"), iter.next()); assert_eq!(Some("few"), iter.next()); assert_eq!(Some("words"), iter.next()); assert_eq!(None, iter.next());
考虑到不同类型的空格:
let mut iter = " Mary had\ta little \n\t lamb".split_ascii_whitespace(); assert_eq!(Some("Mary"), iter.next()); assert_eq!(Some("had"), iter.next()); assert_eq!(Some("a"), iter.next()); assert_eq!(Some("little"), iter.next()); assert_eq!(Some("lamb"), iter.next()); assert_eq!(None, iter.next());
pub fn lines(&self) -> Lines
字符串行迭代器,作为字符串切片。
行以换行符(\n)结束或带换行符(\r\n)的回车符结束。
最后一行的结尾是可选的。
使用:
let text = "foo\r\nbar\n\nbaz\n"; let mut lines = text.lines(); assert_eq!(Some("foo"), lines.next()); assert_eq!(Some("bar"), lines.next()); assert_eq!(Some(""), lines.next()); assert_eq!(Some("baz"), lines.next()); assert_eq!(None, lines.next());
最后一行不需要:
let text = "foo\nbar\n\r\nbaz"; let mut lines = text.lines(); assert_eq!(Some("foo"), lines.next()); assert_eq!(Some("bar"), lines.next()); assert_eq!(Some(""), lines.next()); assert_eq!(Some("baz"), lines.next()); assert_eq!(None, lines.next());
pub fn lines_any(&self) -> LinesAny
1.4.0之后弃用,请使用lines()
pub fn encode_utf16(&self) -> EncodeUtf16
UTF-16编码的字符串迭代器
使用:
let text = "Zażółć gęślą jaźń"; let utf8_len = text.len(); let utf16_len = text.encode_utf16().count(); assert!(utf16_len <= utf8_len);
pub fn contains<'a, P>(&'a self, pat: P) -> bool where P: Pattern<'a>,
判断是否含有对应的子串
使用:
let bananas = "bananas"; assert!(bananas.contains("nana")); assert!(!bananas.contains("apples"));
pub fn starts_with<'a, P>(&'a self, pat: P) -> bool where P: Pattern<'a>,
判断字符串头是否与子串匹配
使用:
let bananas = "bananas"; assert!(bananas.starts_with("bana")); assert!(!bananas.starts_with("nana"));
pub fn ends_with<'a, P>(&'a self, pat: P) -> bool where P: Pattern<'a>, <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
判断字符串尾是否与子串匹配
使用:
let bananas = "bananas"; assert!(bananas.ends_with("anas")); assert!(!bananas.ends_with("nana"));
pub fn find<'a, P>(&'a self, pat: P) -> Option<usize> where P: Pattern<'a>,
返回与模式匹配的此字符串切片的第一个字符的字节索引。
如果模式不匹配,则返回None。
模式可以是&str,char或确定字符是否匹配的闭包。
简单匹配:
let s = "Löwe 老虎 Léopard"; assert_eq!(s.find('L'), Some(0)); assert_eq!(s.find('é'), Some(14)); assert_eq!(s.find("Léopard"), Some(13));
更复杂的匹配:
let s = "Löwe 老虎 Léopard"; assert_eq!(s.find(char::is_whitespace), Some(5)); assert_eq!(s.find(char::is_lowercase), Some(1)); assert_eq!(s.find(|c: char| c.is_whitespace() || c.is_lowercase()), Some(1)); assert_eq!(s.find(|c: char| (c < 'o') && (c > 'a')), Some(4));
未找到匹配项:
let s = "Löwe 老虎 Léopard"; let x: &[_] = &['1', '2']; assert_eq!(s.find(x), None);
pub fn rfind<'a, P>(&'a self, pat: P) -> Option<usize> where P: Pattern<'a>, <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
返回与模式匹配的此字符串切片的最后一个字符的字节索引。
如果模式不匹配,则返回None。
模式可以是&str,char或确定字符是否匹配的闭包。
简单匹配:
let s = "Löwe 老虎 Léopard"; assert_eq!(s.rfind('L'), Some(13)); assert_eq!(s.rfind('é'), Some(14));
更复杂的匹配:
let s = "Löwe 老虎 Léopard"; assert_eq!(s.rfind(char::is_whitespace), Some(12)); assert_eq!(s.rfind(char::is_lowercase), Some(20));
未找到匹配项:
let s = "Löwe 老虎 Léopard"; let x: &[_] = &['1', '2']; assert_eq!(s.rfind(x), None);
pub fn split<'a, P>(&'a self, pat: P) -> Split<'a, P> where P: Pattern<'a>,
字符串片段的子字符串迭代器,该迭代器由与模式匹配的字符分隔。
模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。
迭代器行为
如果模式允许反向搜索并且正向/反向搜索产生相同的元素,则返回的迭代器将为DoubleEndedIterator。 例如,对于char是这样,但对于&str则不是。
如果模式允许反向搜索,但其结果可能与正向搜索不同,则可以使用rsplit方法。
简单匹配:
let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); let v: Vec<&str> = "".split('X').collect(); assert_eq!(v, [""]); let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect(); assert_eq!(v, ["lion", "", "tiger", "leopard"]); let v: Vec<&str> = "lion::tiger::leopard".split("::").collect(); assert_eq!(v, ["lion", "tiger", "leopard"]); let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect(); assert_eq!(v, ["abc", "def", "ghi"]); let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect(); assert_eq!(v, ["lion", "tiger", "leopard"]);
更复杂的匹配:
let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect(); assert_eq!(v, ["abc", "def", "ghi"]);
如果一个字符串包含多个连续的分隔符,您将在输出中得到空字符串:
let x = "||||a||b|c".to_string(); let d: Vec<_> = x.split('|').collect(); assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
连续的分隔符由空字符串分隔。
let x = "(///)".to_string(); let d: Vec<_> = x.split('/').collect(); assert_eq!(d, &["(", "", "", ")"]);
字符串开头或结尾的分隔符与空字符串相邻。
let d: Vec<_> = "010".split("0").collect(); assert_eq!(d, &["", "1", ""]);
当空字符串用作分隔符时,它将字符串中的每个字符以及字符串的开头和结尾分开。
let f: Vec<_> = "rust".split("").collect(); assert_eq!(f, &["", "r", "u", "s", "t", ""]);
当使用空格作为分隔符时,连续的分隔符可能导致令人惊讶的行为。 该代码是正确的:
let x = " a b c".to_string(); let d: Vec<_> = x.split(' ').collect(); assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
若想输出:
assert_eq!(d, &["a", "b", "c"]);
请使用split_whitespace
pub fn rsplit<'a, P>(&'a self, pat: P) -> RSplit<'a, P> where P: Pattern<'a>, <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
参照
```pub fn split<'a, P>(&'a self, pat: P) -> RSplit<'a, P>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
从尾部向前匹配 >简单匹配:
let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
let v: Vec<&str> = "".rsplit('X').collect();
assert_eq!(v, [""]);
let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
assert_eq!(v, ["leopard", "tiger", "", "lion"]);
let v: Vec<&str> = "lion:🐯:leopard".rsplit("::").collect();
assert_eq!(v, ["leopard", "tiger", "lion"]);
使用闭包的更复杂的匹配模式:
let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
assert_eq!(v, ["ghi", "def", "abc"]);
>-------------------------------------------------------------
pub fn split_terminator<'a, P>(&'a self, pat: P) -> SplitTerminator<'a, P>
where
P: Pattern<'a>,
> 给定字符串切片的子字符串上的迭代器,该子字符串由与模式匹配的字符分隔。 > 模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。 >等效于split,不同之处在于尾随的子字符串为空时将被跳过。 > 此方法可用于终止的字符串数据,而不用模式分隔(原文:This method can be used for string data that is terminated, rather than separated by a pattern)。 迭代器行为 > 如果模式允许反向搜索并且正向/反向搜索产生相同的元素,则返回的迭代器将为DoubleEndedIterator。 例如,对于char是这样,但对于&str则不是。 > 如果该模式允许反向搜索,但其结果可能与正向搜索不同,则可以使用rsplit_terminator方法。 > 使用:
let v: Vec<&str> = "A.B.".split_terminator('.').collect();
assert_eq!(v, ["A", "B"]);
let v: Vec<&str> = "A..B..".split_terminator(".").collect();
assert_eq!(v, ["A", "", "B", ""]);
>---------------------------------------------------
pub fn rsplit_terminator<'a, P>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
> 在self的子字符串上进行迭代的迭代器,该迭代器由与模式匹配的字符分隔并以相反的顺序产生。 > 模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。 其他库可能会提供更复杂的模式,例如正则表达式。 > 等效于split,不同之处在于尾随的子字符串为空时将被跳过。 > 此方法可用于终止的字符串数据,而不用模式分隔。 迭代器行为 >返回的迭代器要求模式支持反向搜索,如果正向/反向搜索产生相同的元素,则它将是双头模式。 > 从开始进行迭代,请使用split_terminator方法。 > 使用:
let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
assert_eq!(v, ["B", "A"]);
let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
assert_eq!(v, ["", "B", "", "A"]);
>---------------------------------------------------
pub fn splitn<'a, P>(&'a self, n: usize, pat: P) -> SplitN<'a, P>
where
P: Pattern<'a>,
> 给定字符串切片的子字符串的迭代器,由模式分隔,最多只能返回n个项目。 > 如果返回n个子字符串,则最后一个子字符串(第n个子字符串)将包含字符串的其余部分。 > 模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。 迭代器行为 > 返回的迭代器不会是双向的,因为支持效率不高。 > 如果模式允许反向搜索,则可以使用rsplitn方法。 简单匹配:
let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
assert_eq!(v, ["Mary", "had", "a little lambda"]);
let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
assert_eq!(v, ["lion", "", "tigerXleopard"]);
let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
assert_eq!(v, ["abcXdef"]);
let v: Vec<&str> = "".splitn(1, 'X').collect();
assert_eq!(v, [""]);
使用闭包的更复杂的匹配:
let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
assert_eq!(v, ["abc", "defXghi"]);
>---------------------------------------------------------
pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
> 从字符串的末尾开始,在此字符串切片的子字符串上进行迭代的迭代器,由模式分隔,限制为最多返回n个项目。 > 如果返回n个子字符串,则最后一个子字符串(第n个子字符串)将包含字符串的其余部分。 > 模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。 迭代器行为 > 返回的迭代器不会是双向的,因为支持效率不高。 > 要从头部开始拆分,请使用splitn方法。 简单匹配:
let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
assert_eq!(v, ["lamb", "little", "Mary had a"]);
let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
assert_eq!(v, ["leopard", "tiger", "lionX"]);
let v: Vec<&str> = "lion:🐯:leopard".rsplitn(2, "::").collect();
assert_eq!(v, ["leopard", "lion::tiger"]);
使用闭包的更复杂的匹配:
let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
assert_eq!(v, ["ghi", "abc1def"]);
>---------------------------------------------------------------
pub fn matches<'a, P>(&'a self, pat: P) -> Matches<'a, P>
where
P: Pattern<'a>,
> 给定字符串切片中某个模式的不相交匹配的迭代器。 > 模式可以是实现模式特征的任何类型。 值得注意的示例是&str,char和确定拆分的闭包。 迭代器行为 > 如果模式允许反向搜索并且正向/反向搜索产生相同的元素,则返回的迭代器将为DoubleEndedIterator。 例如,对于char是这样,但对于&str则不是。 > 如果模式允许反向搜索,但其结果可能与正向搜索不同,则可以使用rmatches方法。 > 使用:
let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
assert_eq!(v, ["abc", "abc", "abc"]);
let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
assert_eq!(v, ["1", "2", "3"]);
>----------------------------------------------------
pub fn rmatches<'a, P>(&'a self, pat: P) -> RMatches<'a, P>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
> 在此字符串片段内某个模式的不相交匹配上进行迭代的迭代器,从尾部开始。 > 模式可以是&str,char或确定字符是否匹配的闭包。 迭代器行为 > 返回的迭代器要求该模式支持反向搜索,如果正向/反向搜索产生相同的元素,则它将为DoubleEndedIterator。 > 从头部开始迭代,请使用matchs方法。 > 使用:
let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
assert_eq!(v, ["abc", "abc", "abc"]);
let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
assert_eq!(v, ["3", "2", "1"]);
>---------------------------------------------
pub fn match_indices<'a, P>(&'a self, pat: P) -> MatchIndices<'a, P>
where
P: Pattern<'a>,
> 在此字符串切片内模式的不相交匹配以及匹配开始处的索引上的迭代器。 > 对于自身重叠的pat匹配,仅返回与第一个匹配相对应的索引。 > 模式可以是&str,char或确定字符是否匹配的闭包。 迭代器行为 >如果模式允许反向搜索并且正向/反向搜索产生相同的元素,则返回的迭代器将为DoubleEndedIterator。 对于char是这样,但对于&str则不是。 >如果该模式允许反向搜索,但其结果可能与正向搜索不同,则可以使用rmatch_indices方法。 > 使用:
let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
assert_eq!(v, [(1, "abc"), (4, "abc")]);
let v: Vec<_> = "ababa".match_indices("aba").collect();
assert_eq!(v, [(0, "aba")]); // only the first aba
>------------------------------------------------------------
pub fn rmatch_indices<'a, P>(&'a self, pat: P) -> RMatchIndices<'a, P>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
> 在自身中某个模式的不相交匹配项上进行迭代的迭代器,其顺序与匹配项的索引相反。 > 对于自身重叠的pat匹配,仅返回与最后一个匹配相对应的索引。 > 模式可以是&str,char或确定字符是否匹配的闭包。 迭代器行为 >返回的迭代器要求该模式支持反向搜索,如果正向/反向搜索产生相同的元素,则它将为DoubleEndedIterator。 >需要从头部开始迭代,请使用match_indices方法。 > 使用:
let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
assert_eq!(v, [(4, "abc"), (1, "abc")]);
let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
assert_eq!(v, [(2, "aba")]); // only the last aba
## 扩展属性
pub fn trim(&self) -> &str
> 返回除去前导和尾随空格的字符串切片。 > “空白”是根据Unicode派生核心属性White_Space的术语定义的。 > 使用:
let s = " Hello\tworld\t";
assert_eq!("Hello\tworld", s.trim());
>------------------------------------------------------
pub fn trim_start(&self) -> &str
> 返回除去前导空格的字符串切片。 > “空白”是根据Unicode派生核心属性White_Space的术语定义的。 文字方向性 >字符串是字节序列。 在此上下文中,start表示该字节字符串的第一个位置; 对于从左到右的语言(如英语或俄语),这将是左侧;对于从右到左的语言(如阿拉伯语或希伯来语),将是右侧。 > 使用:
let s = " Hello\tworld\t";
assert_eq!("Hello\tworld\t", s.trim_start());
let s = " English ";
assert!(Some('E') == s.trim_start().chars().next());
let s = " עברית ";
assert!(Some('ע') == s.trim_start().chars().next());
>------------------------------------------------------
pub fn trim_end(&self) -> &str
> 返回除去尾部空格的字符串切片。 > “空白”是根据Unicode派生核心属性White_Space的术语定义的。 文字方向性 >字符串是字节序列。 在此上下文中,start表示该字节字符串的最后一个位置; 对于从左到右的语言(如英语或俄语),这将是右侧;对于从右到左的语言(如阿拉伯语或希伯来语),将是左侧。 > 使用:
let s = " Hello\tworld\t";
assert_eq!(" Hello\tworld", s.trim_end());
let s = " English ";
assert!(Some('h') == s.trim_end().chars().rev().next());
let s = " עברית ";
assert!(Some('ת') == s.trim_end().chars().rev().next());
> -------------------------------------------------------------
pub fn trim_left(&self) -> &str
> 从1.33.0开始弃用,请使用trim_start >-------------------------------------------------------------
pub fn trim_right(&self) -> &str
> 从1.33.0开始弃用,请使用trim_end >-------------------------------------------------------------
pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: DoubleEndedSearcher<'a>,
> 返回具有与重复删除的模式匹配的所有前缀和后缀的字符串切片。 > 该模式可以是一个char或一个确定字符是否匹配的闭包。 简单匹配:
assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
let x: &[_] = &['1', '2'];
assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
使用闭包的复杂匹配:
assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
>-------------------------------------------------------------
pub fn trim_start_matches<'a, P>(&'a self, pat: P) -> &'a str
where
P: Pattern<'a>,
> 返回具有与重复删除的模式匹配的所有前缀的字符串切片。 > 模式可以是&str,char或确定字符是否匹配的闭包。 文字方向性 >字符串是字节序列。 在此上下文中,start表示该字节字符串的第一个位置; 对于从左到右的语言(如英语或俄语),这将是左侧;对于从右到左的语言(如阿拉伯语或希伯来语),将是右侧。 >使用:
assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11");
assert_eq!("123foo1bar123".trim_start_matches(char::is_numeric), "foo1bar123");
let x: &[_] = &['1', '2'];
assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12");
>------------------------------------------------------------
pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
> 返回具有与模式重复删除的所有后缀的字符串切片。 > 模式可以是&str,char或确定字符是否匹配的闭包。 文字方向性 > 字符串是字节序列。 在此上下文中的end表示该字节字符串的最后位置; 对于从左到右的语言(例如英语或俄语),这将在右侧;对于从右到左的语言(例如阿拉伯语或希伯来语),将在左侧。 简单匹配:
assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar");
assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar");
let x: &[_] = &['1', '2'];
assert_eq!("12foo1bar12".trim_end_matches(x), "12foo1bar");
使用闭包的复杂匹配:
assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo");
>----------------------------------------------------------
pub fn trim_left_matches<'a, P>(&'a self, pat: P) -> &'a str
where
P: Pattern<'a>,
> 1.33.0后不推荐使用,请使用trim_start_matches >------------------------------------------------------------
pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
[src] [−] > 1.33.0后不推荐使用,请使用trim_end_matches >----------------------------------------------------------
pub fn parse
where
F: FromStr,
> 将此字符串切片解析为另一种类型。 > 由于解析是如此笼统,因此可能导致类型推断问题。 因此,解析是您会发现几次被亲切地称为“ turbofish”的语法之一的:::>。 这可以帮助推理算法特别了解您要解析为哪种类型。 > parse可以解析实现FromStr特征的任何类型。 > 如果无法将此字符串切片解析为所需的类型,则将返回Err。 > 使用:
let four: u32 = "4".parse().unwrap();
assert_eq!(4, four);
Run
Using the 'turbofish' instead of annotating four:
let four = "4".parse::
assert_eq!(Ok(4), four);
失败的转换:
let nope = "j".parse::
assert!(nope.is_err());
>----------------------------------------------------------------
pub fn is_ascii(&self) -> bool
> 判断是否所有字符都是ASCII字符 >使用:
let ascii = "hello!\n";
let non_ascii = "Grüße, Jürgen ❤";
assert!(ascii.is_ascii());
assert!(!non_ascii.is_ascii());
>--------------------------------------------------------------------
pub fn eq_ignore_ascii_case(&self, other: &str) -> bool
> 判断两个字符串是否为ASCII不区分大小写的匹配项。 > 与to_ascii_lowercase(a)== to_ascii_lowercase(b)相同,但不分配和复制临时对象。 > 使用:
assert!("Ferris".eq_ignore_ascii_case("FERRIS"));
assert!("Ferrös".eq_ignore_ascii_case("FERRöS"));
assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
>-------------------------------------------------------------
pub fn make_ascii_uppercase(&mut self)
> 将此字符串就地转换为其ASCII大写等效项。 > ASCII字母“ a”至“ z”映射到“ A”至“ Z”,但非ASCII字母不变。 > 要返回新的大写值而不修改现有值,请使用to_ascii_uppercase。 > 使用
let mut s = String::from("Grüße, Jürgen ❤");
s.make_ascii_uppercase();
assert_eq!("GRüßE, JüRGEN ❤", s);
>---------------------------------------------------------
pub fn make_ascii_lowercase(&mut self)
> 将此字符串就地转换为其ASCII小写等效项。 > ASCII字母“ A”至“ Z”映射为“ a”至“ z”,但非ASCII字母不变。 > 要返回新的小写值而不修改现有值,请使用to_ascii_lowercase。 > 使用:
let mut s = String::from("GRÜßE, JÜRGEN ❤");
s.make_ascii_lowercase();
assert_eq!("grÜße, jÜrgen ❤", s);
>-------------------------------------------------------------
pub fn escape_debug(&self) -> EscapeDebug
> 返回一个迭代器,该迭代器使用char::escape_debug来转义自身中的每个char。 > 注意:仅以字符串开头的扩展字素代码点将被转义。 使用迭代器:
for c in "❤\n!".escape_debug() {
print!("{}", c);
}
println!();
用println!直接转换:
println!("{}", "❤\n!".escape_debug());
println!("❤\n!");
assert_eq!("❤\n!".escape_debug().to_string(), "❤\n!");
>-------------------------------------------------------------
pub fn escape_default(&self) -> EscapeDefault
> 返回一个迭代器,该迭代器使用char::escape_default自身转义每个char。 使用迭代器:
for c in "❤\n!".escape_default() {
print!("{}", c);
}
println!();
用println!直接转换:
println!("{}", "❤\n!".escape_default());
println!("\u{{2764}}\n!");
assert_eq!("❤\n!".escape_default().to_string(), "\u{2764}\n!");
>-----------------------------------------------------------------
pub fn escape_unicode(&self) -> EscapeUnicode
> 返回一个迭代器,该迭代器使用char::escape_unicode自身转义每个char。 使用迭代器:
for c in "❤\n!".escape_unicode() {
print!("{}", c);
}
println!();
用println!直接转换::
println!("{}", "❤\n!".escape_unicode());
println!("\u{{2764}}\u{{a}}\u{{21}}");
assert_eq!("❤\n!".escape_unicode().to_string(), "\u{2764}\u{a}\u{21}");
>-----------------------------------------------------------
pub fn replace<'a, P>(&'a self, from: P, to: &str) -> String
where
P: Pattern<'a>,
> 用另一个字符串替换模式的所有匹配项。 > replace创建一个新的String,并将数据从该string slice中复制到其中。 这样做时,它将尝试查找某个模式的匹配项。 如果找到任何内容,它将用替换字符串切片替换它们。 > 使用:
let s = "this is old";
assert_eq!("this is new", s.replace("old", "new"));
不匹配时,无任何操作:
let s = "this is old";
assert_eq!(s, s.replace("cookie monster", "little lamb"));
>-----------------------------------------------------
pub fn replacen<'a, P>(&'a self, pat: P, to: &str, count: usize) -> String where
P: Pattern<'a>,
> 用另一个字符串替换模式的前N个匹配项。 > replacen创建一个新的String,并将数据从该字符串切片复制到其中。 这样做时,它将尝试查找某个模式的匹配项。 如果找到任何内容,则最多在计数时间内用替换字符串切片替换它们。 > 使用:
let s = "foo foo 123 foo";
assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));
不匹配时,无任何操作::
let s = "this is old";
assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
>-------------------------------------------------------------
pub fn to_lowercase(&self) -> String
> 以新的String形式返回等效于此字符串片段的小写字母。 > “小写”是根据Unicode派生核心属性小写的术语定义的。 > 由于更改大小写时某些字符可以扩展为多个字符,因此此函数返回新的String而不是就地修改参数。 使用:
let s = "HELLO";
assert_eq!("hello", s.to_lowercase());
特殊字符:
let sigma = "Σ";
assert_eq!("σ", sigma.to_lowercase());
// but at the end of a word, it's ς, not σ:
let odysseus = "ὈΔΥΣΣΕΎΣ";
assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
没有大小写的不变:
let new_year = "农历新年";
assert_eq!(new_year, new_year.to_lowercase());
>-----------------------------------------------------------
pub fn to_uppercase(&self) -> String
> 以新的String形式返回此字符串切片的大写等效项。 > “大写”是根据Unicode派生核心属性大写的术语定义的。 > 由于更改大小写时某些字符可以扩展为多个字符,因此此函数返回String而不是就地修改参数。 使用:
let s = "hello";
assert_eq!("HELLO", s.to_uppercase());
没有大小写的不变:
let new_year = "农历新年";
assert_eq!(new_year, new_year.to_uppercase());
一个字符可以变成多个:
let s = "tschüß";
assert_eq!("TSCHÜSS", s.to_uppercase());
>------------------------------------------------------------
pub fn repeat(&self, n: usize) -> String
>通过重复一个字符串n次来创建一个新的字符串。 >如果容量溢出,此功能将出现错误。 使用:
assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
超长溢出:
fn main() {
// this will panic at runtime
"0123456789abcdef".repeat(usize::max_value());
}
>---------------------------------------------------
pub fn to_ascii_uppercase(&self) -> String
> 返回此字符串的副本,其中每个字符都映射为其等效的ASCII大写字母。 > ASCII字母“ a”至“ z”映射到“ A”至“ Z”,但非ASCII字母不变。 > 要就地改写,请使用make_ascii_uppercase。 > 包含非ASCII字符,请使用to_uppercase。 使用:
let s = "Grüße, Jürgen ❤";
assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
>----------------------------------------------------------
pub fn to_ascii_lowercase(&self) -> String
> 返回此字符串的副本,其中每个字符都映射为其等效的ASCII小写字母。 > ASCII字母“ A”至“ Z”映射为“ a”至“ z”,但非ASCII字母不变。 > 要就地改写,请使用make_ascii_lowercase。 > 包含非ASCII字符时,请使用to_lowercase。 使用
let s = "Grüße, Jürgen ❤";
assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
```
接口实现(Trait Implementations)
impl FromStr for String
impl Eq for String
impl Deref for String
impl From
for Rc
impl From
for Arc
impl<'> From<&' String> for String
impl<'a> From<Cow<'a, str>> for String
impl<'a> From
for Cow<'a, str>
impl From
for Vec
impl<'> From<&' str> for String
impl From
for Box
impl<'a> From<&'a String> for Cow<'a, str>
impl From<Box
> for String
impl Hash for String
impl<'a, 'b> PartialEq
for Cow<'a, str>
impl<'a, 'b> PartialEq
for &'a str
impl<'a, 'b> PartialEq
for str
impl<'a, 'b> PartialEq
for String
impl<'a, 'b> PartialEq<&'a str> for String
impl<'a, 'b> PartialEq<Cow<'a, str>> for String
impl PartialEq
for String
impl IndexMut
for String
impl IndexMut<Range
> for String
impl IndexMut<RangeToInclusive
> for String
impl IndexMut<RangeTo
> for String
impl IndexMut<RangeFrom
> for String
impl IndexMut<RangeInclusive
> for String
impl AsRef
for String
impl AsRef<[u8]> for String
impl<'> AddAssign<&' str> for String
impl<'a> FromIterator
for Cow<'a, str>
impl FromIterator
for String
impl<'a> FromIterator<&'a str> for String
impl<'a> FromIterator<Cow<'a, str>> for String
impl<'a> FromIterator<&'a char> for String
impl FromIterator
for String
impl<'a, 'b> Pattern<'a> for &'b String
impl Index
for String
impl Index<RangeFrom
> for String
impl Index<RangeInclusive
> for String
impl Index<RangeToInclusive
> for String
impl Index<Range
> for String
impl Index<RangeTo
> for String
impl Display for String
impl Borrow
for String
impl Ord for String
impl Clone for String
impl BorrowMut
for String
impl Debug for String
impl ToString for String
impl<'> Add<&' str> for String
impl PartialOrd
for String
impl Default for String
impl Write for String
impl DerefMut for String
impl Extend
for String
impl<'a> Extend<&'a str> for String
impl Extend
for String
impl<'a> Extend<&'a char> for String
impl<'a> Extend<Cow<'a, str>> for String
impl ToSocketAddrs for String
impl From
for Box<dyn Error + Send + Sync>
impl From
for Box
impl From
for OsString
impl From
for PathBuf
impl AsRef
for String
impl AsRef
for String
自动接口实现(Auto Trait Implementations)
- impl UnwindSafe for String
- impl RefUnwindSafe for String
- impl Unpin for String
- impl Send for String
impl Sync for String
Blanket Implementations
impl
From for T
impl<T, U> TryFrom for T where
U: Into,
impl<T, U> Into for T where
U: From,
impl<T, U> TryInto for T where
U: TryFrom,
impl
Borrow for T where
T: ?Sized,
impl
BorrowMut for T where
T: ?Sized,
impl
Any for T where
T: 'static + ?Sized,
impl
ToOwned for T where
T: Clone,
impl
ToString for T where
T: Display + ?Sized,