原文链接: https://www.ffactory.org/2021/09/30/go-to-rust-string
# 通过golang和rust代码对比快速学习rust(2)- 字符串
## 1. 字符串类型定义
- Golang 中只有一个 string类型,对应字符串。
> string是所有8位字节的字符串的集合,通常但不一定代表UTF-8编码的文本。一个字符串可以是空的,但不能是零。字符串类型的值是不可改变的。
- Rust 中有三个类型 str ,&str ,String 来对应处理字符串。
> str类型,也被称为 "字符串切片",是最原始的字符串类型。它通常以其借用的形式出现,即&str。它也是字符串字面的类型,&'static str。字符串切片总是有效的UTF-8。
&str类型是两个主要的字符串类型之一,另一个是String。与其对应的String不同,它的内容是借用的。
String类型是一个UTF-8编码的、可增长的字符串。
String类型是最常见的字符串类型,它对字符串的内容有所有权。它与它的借来的对应物,即原始的str,有着密切的关系。
## 2. 个人理解
> Golang中字符串只用stirng处理,实际存储的是byte数组。type byte = uint8,也就是uint8数组不可变。要对字符串做遍历直接就可以用索引。如果要变更长度,需要使用strings包的Split,Join等函数修改并返回一个新的字符串。
> Rust中字符串是str,实际存储的是u8数组不可变,以&str获取u8数组的切片来访问,遍历。要对字符串做增长修改操作,需要转换成String处理。
> Golang中对字符串的拆分,组合字符串,通过包strings处理。Rust中通过把字符串转成String实际是pub struct String { vec: Vec<u8>,}结构,是一个处理字符串的对象,它附带了很多处理字符串的方法函数。但是它不是字符串。Rust的String对象等价于Go中的包strings。
> (作为一个Golang开发者学习Rust,非常容易把Rust的String 等价于 Golang中的string 这是个错误。)
## 3. 我的困惑:
Rust中对String的说明太让人难以理解了:
原文:
>A UTF-8–encoded, growable string.
>The String type is the most common string type that has ownership over the contents of the string. It has a close relationship with its borrowed counterpart, the primitive str.
建议应该改成
>An object that performs growth processing on UTF-8 encoded strings.
>The String object is the most common set of string growth processing methods, and it has ownership over the content of the string. It has a close relationship with its borrowed counterpart, the original str. It can do splitting, combining, and growing of strings to return a new string.
## 4. 比较代码
通过代码比较更容易理解Golang和Rust对字符串处理的差异。代码如下:
### Golang 代码
```go
package main
import (
"fmt"
"strings"
)
func main() {
var s string = "Hello, 世界"
fmt.Println(s)
fmt.Printf("%v\n", s)
fmt.Println("len:", len(s))
fmt.Println(strings.Split(s, ""))
for _, v := range strings.Split(s, "") {
fmt.Println("char:", v)
}
fmt.Println([]byte(s))
for _, v := range s {
fmt.Println("byte:", v)
}
var c = 'a'
fmt.Println("c:", c)
// 字符串连接
var s2 string = s + "!"
fmt.Println("连接后的字符串:", s2)
// utf8 字符串字面亮赋值
var hello string = "Hello, world!🚢"
fmt.Println(hello)
}
```
output:
```
Hello, 世界
Hello, 世界
len: 13
[H e l l o , 世 界]
char: H
char: e
char: l
char: l
char: o
char: ,
char:
char: 世
char: 界
[72 101 108 108 111 44 32 228 184 150 231 149 140]
byte: 72
byte: 101
byte: 108
byte: 108
byte: 111
byte: 44
byte: 32
byte: 19990
byte: 30028
c: 97
连接后的字符串: Hello, 世界!
Hello, world!🚢
```
### Rust 代码
```go
fn main() {
let s: &str = "Hello, 世界";
println!("{}", s);
println!("{:?}", s);
println!("len:{}", s.len());
println!("{:?}",s.chars());
for v in s.chars() {
println!("char:{}", v);
}
println!("{:?}",s.bytes());
for v in s.bytes() {
println!("byte:{}", v);
}
let c = 'a';
println!("c:{}", c);
// 字符串连接
let s1: String = s.to_owned() + "!";
let s2: &str = s1.as_str();
println!("连接后的字符串:{}", s2);
// utf8字面量绑定
let hello: &'static str = "Hello, world!🚢";
println!("{}", hello);
}
```
output:
```
Hello, 世界
"Hello, 世界"
len:13
Chars(['H', 'e', 'l', 'l', 'o', ',', ' ', '世', '界'])
char:H
char:e
char:l
char:l
char:o
char:,
char:
char:世
char:界
Bytes(Copied { it: Iter([72, 101, 108, 108, 111, 44, 32, 228, 184, 150, 231, 149, 140]) })
byte:72
byte:101
byte:108
byte:108
byte:111
byte:44
byte:32
byte:228
byte:184
byte:150
byte:231
byte:149
byte:140
c:a
连接后的字符串:Hello, 世界!
Hello, world!🚢
```
有疑问加站长微信联系(非本文作者))