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官方文档翻译(上) 一,数据对象 不论什么不含业 ...
随机推荐
- Canvas绘制圆点线段
最近一个小伙遇到一个需求,客户需要绘制圆点样式的线条. 大致效果是这样的: 思路一:计算并使用arc填充 他自己实现了一种思路,然后咨询我有没有更好的思路. 先看看他的思路是如何实现的,大致代码如下: ...
- 在k8s上部署日志系统elfk
日志系统elfk 前言 经过上周的技术预研,在本周一通过开会研究,根据公司的现有业务流量和技术栈,决定选择的日志系统方案为:elasticsearch(es)+logstash(lo)+filebea ...
- Python Opencv-contrib Camshift&kalman卡尔曼滤波&CSRT算法 目标跟踪实现
本次课题实现目标跟踪一共用到了三个算法,分别是Camshift.Kalman.CSRT,基于Python语言的Tkinter模块实现GUI与接口设计,项目一共包含三个文件: main.py: # co ...
- thinkphp5.0使用官方验证码插件
1.首先使用Composer下载验证码插件. 安装完成后,使用以下命令修改composer配置文件,使用国内镜像.原因你懂的. composer config -g repo.packagist co ...
- Ultra-QuickSort (求逆序数+离散化处理)、Cows、Stars【树状数组】
一.Ultra-QuickSort(树状数组求逆序数) 题目链接(点击) Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total ...
- (三)Maven命令列表
mvn –version 显示版本信息 mvn clean 清理项目生产的临时文件,一般是模块下的target目录 mvn compile 编译源代码,一般编译模块下的src/main/java目录, ...
- TypeError: this.xxx.substring is not a function的解决办法
这是因为已经改变了xxx的值的类型,不再是字符串的话将不会拥有substring函数, 我当时这样写的时候,直接将number类型赋予了this.enter,所以导致了错误. 改为这样之后可以使用su ...
- LR脚本信息函数-lr_start_timer和lr_end_timer
为了计算时间更加精确,可以用这个函数去掉LR自身的检查点所浪费的时间.如text check and image time Action() { double time_elapsed, durati ...
- python获取本地时间戳
import time print(time.time())#获当前时间的时间戳 print(time.localtime())#获取本地时间 print(time.strftime('%Y-%m-% ...
- 手写简易版Promise
实现一个简易版 Promise 在完成符合 Promise/A+ 规范的代码之前,我们可以先来实现一个简易版 Promise,因为在面试中,如果你能实现出一个简易版的 Promise 基本可以过关了. ...