学习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(官方文档翻译)的更多相关文章

  1. 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 ...

  2. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...

  3. GreenDao官方文档翻译(上)

    笔记摘要: 上一篇博客简单介绍了SQLite和GreenDao的比较,后来说要详细介绍下GreenDao的使用,这里就贴出本人自己根据官网的文档进行翻译的文章,这里将所有的文档分成上下两部分翻译,只为 ...

  4. Aircrack-ng官方文档翻译[中英对照]---Airmon-ng

    Aircrack-ng官方文档翻译---Airmon-ng Description[简介] This script can be used to enable monitor mode on wire ...

  5. Retrofit官方文档翻译

    Retrofit官方文档翻译 官方文档网址 http://square.github.io/retrofit/ 介绍 Retrofit 将你的 HTTP API 转换为 Java 接口. public ...

  6. Spring官方文档翻译(1~6章)

    Spring官方文档翻译(1~6章) 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档.参考中文文档 一.S ...

  7. 基本控件文档-UITextField属性---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...

  8. 苹果API常用英语名词---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 苹果API常用英语名词0. indicating 决定1.in order to 以便 ...

  9. kong插件官方文档翻译

    kong插件官方文档翻译 目录 介绍 文件结构 编写自定义逻辑 存储配置 访问数据存储 自定义实体 缓存自定义实体 扩展Admin API 编写测试 (卸载)安装你的插件 插件开发 - 介绍 什么是插 ...

  10. Data Binding Guide——google官方文档翻译(下)

    这篇博客是Data Binding Guide官网文档翻译的下篇.假设没看过前半部分翻译的能够先看Data Binding Guide--google官方文档翻译(上)  一,数据对象 不论什么不含业 ...

随机推荐

  1. 源码分析(2)-LinkedHashMap(JDK1.8)

    1.概述 LinkedHashMap继承自HashMap:在HashMap基础上,通过维护一条双向链表,解决了HashMap键值对遍历顺序和插入顺序一致的问题. 想了解LinkedHashMap源码, ...

  2. SpringSceurity(4)---短信验证码功能实现

    SpringSceurity(4)---短信验证码功能实现 有关SpringSceurity系列之前有写文章 1.SpringSecurity(1)---认证+授权代码实现 2.SpringSecur ...

  3. VSCode最佳设置

    最近在学习Vue,用VSCode开发.经过摸索,VSCode最佳设置. { "eslint.enable": false, "workbench.colorTheme&q ...

  4. 如何在Centos7安装swoole的PHP扩展

    1. 下载swoole源代码包 wget -c https://github.com/swoole/swoole-src/archive/v2.0.8.tar.gz 2.tar -zxvf v2.0. ...

  5. 键盘鼠标共享效率工具----Synergy

    在日常工作中,为了提高工作效率以及用户体验,会一个主机接多个显示器,像程序员一般都是使用两块显示器. 然而,有很多人是和我一样,自己有多台电脑,两个笔记本.公司一个台式机,如何在台机器之间来回切换工作 ...

  6. 循环语句&编码了解

    循环语句&编码了解 用户交互 input: input接收的内容是str 循环语句 if语句 语法规则:        if 条件判断:            代码块1        else ...

  7. 2019-02-15 CSS样式学习——(内容来自mooc北京林业大学web前端开发授课ppt)

    CSS样式的添加方法 行内样式 e.x. 内嵌样式 e.x. 注意内嵌样式写在head标签内: 单独文件(外部式样式表文件) 也是在head标签内插入超链接,sublime+emmet可以用link: ...

  8. pip安装报错: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy

    pip安装报错 解决办法: pip install selenium -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

  9. Python format格式化函数

    参考资料:https://www.runoob.com/python/att-string-format.html 在学习Python的时候碰到了一个很有趣的格式化输入的技巧,下面记录在此. Pyth ...

  10. 《Java并发编程的艺术》第5章 Java中的锁 ——学习笔记

    参考https://www.cnblogs.com/lilinzhiyu/p/8125195.html 5.1 Lock接口 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同 ...