Rust String(官方文档翻译)
学习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
使用:
//
Rust String(官方文档翻译)的更多相关文章
- Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)中一些知识点
Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Flume官方文档翻译--Flume 1.7.0 User Guide (unr ...
- Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)
Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...
- GreenDao官方文档翻译(上)
笔记摘要: 上一篇博客简单介绍了SQLite和GreenDao的比较,后来说要详细介绍下GreenDao的使用,这里就贴出本人自己根据官网的文档进行翻译的文章,这里将所有的文档分成上下两部分翻译,只为 ...
- Aircrack-ng官方文档翻译[中英对照]---Airmon-ng
Aircrack-ng官方文档翻译---Airmon-ng Description[简介] This script can be used to enable monitor mode on wire ...
- Retrofit官方文档翻译
Retrofit官方文档翻译 官方文档网址 http://square.github.io/retrofit/ 介绍 Retrofit 将你的 HTTP API 转换为 Java 接口. public ...
- Spring官方文档翻译(1~6章)
Spring官方文档翻译(1~6章) 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档.参考中文文档 一.S ...
- 基本控件文档-UITextField属性---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...
- 苹果API常用英语名词---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 苹果API常用英语名词0. indicating 决定1.in order to 以便 ...
- kong插件官方文档翻译
kong插件官方文档翻译 目录 介绍 文件结构 编写自定义逻辑 存储配置 访问数据存储 自定义实体 缓存自定义实体 扩展Admin API 编写测试 (卸载)安装你的插件 插件开发 - 介绍 什么是插 ...
- Data Binding Guide——google官方文档翻译(下)
这篇博客是Data Binding Guide官网文档翻译的下篇.假设没看过前半部分翻译的能够先看Data Binding Guide--google官方文档翻译(上) 一,数据对象 不论什么不含业 ...
随机推荐
- 实验三 Linux系统用户管理及VIM配置
项目 内容 这个作业属于哪个课程 班级课程的主页链接 这个作业的要求在哪里 作业要求链接接地址 学号-姓名 17041428-朱槐健 作业学习目标 1.学习Linux系统用户管理 2.学习vim使用 ...
- 超强教程!在树莓派上构建多节点K8S集群!
在很长一段时间里,我对于在树莓派上搭建Kubernetes集群极为感兴趣.在网络上找到一些教程并且跟着实操,我已经能够将Kubernetes安装在树莓派上,并在三个Pi集群中工作.然而,在master ...
- 设计模式系列之工厂模式三兄弟(Factory Pattern)
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- (三)JavaMail发送附件
代码如下: package cases; import com.sun.mail.util.MailSSLSocketFactory; import javax.activation.DataHand ...
- LR脚本信息函数-lr_get_master_host_name
lr_get_master_host_name() 返回Controller主机的名称. char * lr_get_master_host_name(); lr_get_master_host_na ...
- 从零开始的Spring Boot(5、Spring Boot整合Thymeleaf)
Spring Boot整合Thymeleaf 写在前面 从零开始的Spring Boot(4.Spring Boot整合JSP和Freemarker) https://www.cnblogs.com/ ...
- ca12a_c++顺序容器的操作5_访问容器中的数据元素
ca12a_c++顺序容器的操作5_访问容器中的数据元素访问元素:c.back()..显示最后一个数据c.front() ..显示第一个数据c[n],n就是下标,适合vector与dequec.at( ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 网络框架OKHTTP使用场景全解析
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 一.引言 说句实 ...
- Python 程序报错崩溃后,如何倒回到崩溃的位置?
假设我们有一段程序,从 Redis 中读取数据,解析以后提取出里面的 name 字段: import json import redis client = redis.Redis() def read ...