通过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,}结构,是一个处理字符串的对象,它附带了很多处理字符串的方法函数。但是它不是字符串。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 代码

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 代码

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!🚢