Rust字符串字面值的一些经验总结

目录
  • 前言
  • 字符串字面值(String literals)
  • Byte string literals
  • 总结

前言

Rust 中有两种字符串,String 和 &str,其中 String 可动态分配、修改,内部实现可以理解为 Vec<u8>,而 &str 是一个类型为 &[u8] 的切片。这两种字符串都只能保存合法的 UTF-8 字符。

而对于非肉眼可辨识的 UTF-8 字符,则可以考虑使用如下类型:

  • 文件路径有专用的 Path 和 PathBuf 类可用。
  • 使用 Vec<u8> 和 &[u8]
  • 使用 OSString 和 &OSStr 和操作系统交互
  • 使用 CString 和 &CStr 和 C 库交互

上面的第二种方法,就是常用的处理非 UTF-8 字节流的方式,也就是使用 Vec<u8> 和 &[u8] ,其中我们也可以使用字面值来处理这两种类型的数据,我们称之为字节字符串字面值(byte string literals),其类型为 &[u8]。

字符串字面值(String literals)

先来看一下字符串字面值。

和其他语言一样,用双引号括起来就是一个字符串,不过 Rust 的一个特点是字符串可以跨行,即中间有回车也不会引起编译或运行错误,在输出的时候也会带着里面的换行符。

同样,字符串字面值里面支持转义,比如想在里面使用双引号,该转义也会对换行符进行转义,比如下面这样,在换行符前面使用 \ ,则该转义符、换行符以及下一行开头的所有空格都将会被忽略:

let a = "foobar";
let b = "foo\
         bar";
assert_eq!(a,b);

字符串字面值除了支持常见的 \ 对字节(字符)进行转义,还支持对 Unicode 进行转义:

  • \xHH: + 2位的十六进制7位宽度字节码,这相当于等值的 ASCII 字符。
  • \u{xxxx}:24位长的16进制,表示等值的 Unicode 字符。
  • \n/\r/\t 表示 U+000A (LF), U+000D (CR) 和 U+0009 (HT)
  • \\ 用来对 \ 本身进行转义
  • \0 表示 Unicode U+0000 (NUL)

Raw 类型的字符串字面值表示进行转义,也就是说字面值写的是什么内容,字符串的值就是什么。这种类型的字面值使用 r 以及若干 # 开头进行定义,结尾需要相等数量的 #。

如下所示:

"foo"; r"foo";                     // foo
"\"foo\""; r#""foo""#;             // "foo"

"foo #\"# bar";
r##"foo #"# bar"##;                // foo #"# bar

"\x52"; "R"; r"R";                 // R
"\\x52"; r"\x52";                  // \x52

如果字符串中有双引号怎么办?因为 raw string 里不能使用转义,所以 \" 是肯定不行的。Rust 实际支持使用 r# 的方式来指定字符串边界。这个 # 就是转义的另一种实现方式,比如字符串里面有 4 个 #,那么该字符串可以用 r#####"abc####def"##### 来包围起来,也就是比里面的 # 多即可。

Byte string literals

Byte string 字面值使用 b"..." 以及衍生语法定义,其类型为 &[u8],这个和 &str 是完全不一样的类型,所以有些在 &str 上能用的方法,在 &[u8] 上是用不了的。

比如:

// &[u8; 5]: [119, 111, 114, 108, 100]!
let world = b"world";
println!("Hello, {}!", world);

编译会报错,因为 &[u8] 没有实现 std::fmt::Display:

29 |     println!("Hello, {}!", world);
   |                            ^^^^^ `[u8; 5]` cannot be formatted with the default formatter
   |

= help: the trait `std::fmt::Display` is not implemented for `[u8; 5]`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

Byte string 字面值也支持转义,但是需要注意它只支持字节转义,不支持 Unicode 转义。

// 支持字符转义,输出:Hello, Rust!
let escaped = b"\x52\x75\x73\x74 as bytes";

// 不支持 Unicode 转义,编译错误:
// = help: unicode escape sequences cannot be used as a byte or in a byte string
let escaped = b"\u{211D} is not allowed";
// Raw byte strings work just like raw strings
let raw_bytestring = br"\u{211D} is not escaped here";
println!("{:?}", raw_bytestring);

// Converting a byte array to `str` can fail
if let Ok(my_str) = str::from_utf8(raw_bytestring) {
    println!("And the same as text: '{}'", my_str);
}

字节字符串也支持 raw 定义,和标准字符串类型类似,使用 r 前缀定义 raw byte string 字面值变量。

例如下面的例子中普通的字节字符串需要转义,raw 字节字符串就不需要使用 \ 进行转义了。

b"foo"; br"foo";                     // foo
b"\"foo\""; br#""foo""#;             // "foo"

b"foo #\"# bar";
br##"foo #"# bar"##;                 // foo #"# bar

b"\x52"; b"R"; br"R";                // R
b"\\x52"; br"\x52";                  // \x52

总结

下面是刚才介绍的这几种字符串字面值定义的一个总结,列出了不同的定义方式和其含义。

符合    意义
“…”    字符串字面值
r"…“, r#”…“#, r##”…“##, etc.    Raw 字符串字面值,禁止转义
b"…“    字节字符串字面值,类型为 &[u8]
br"…“, br#”…“#, br##”…“##, etc.    Raw 字节字符串字面值
‘…’    字符字面值
b'…‘    ASCII字节字面值

参考资料

到此这篇关于Rust字符串字面值的文章就介绍到这了,更多相关Rust字符串字面值内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Rust 函数详解

    目录 函数参数 函数返回值 高阶函数 函数指针类型 函数作为参数 函数作为返回值 相关资料 Rust 支持多种编程范式,但更偏向于函数式,函数在 Rust 中是"一等公民",函数可以作为数据在程序中进行传递.跟 C.C++ 一样, Rust 也有一个唯一的程序入口 main 函数. 示例:程序入口 main 函数 fn main() { println!("Hello, world!"); } Rust 使用 fn 关键字来声明和定义函数,使用 snake case

  • Rust 中的文件操作示例详解

    目录 文件路径 文件创建和删除 目录创建和删除 文件创建和删除 文件读取和写入 文件打开 文件读取 文件写入 相关资料 文件路径 想要打开或者创建一个文件,首先要指定文件的路径. Rust 中的路径操作是跨平台的,std::path 模块提供的了两个用于描述路径的类型: PathBuf – 具有所有权并且可被修改,类似于 String. Path – 路径切片,类似于 str. 示例: use std::path::Path; use std::path::PathBuf; fn main()

  • 聊聊Rust 运算符

    目录 一元运算符 二元运算符 算数操作符 位运算符 惰性 boolean 运算符 比较运算符 类型转换运算符 重载运算符 格式化字符串 一元运算符 顾名思义,一元操作符是专门对一个 Rust 元素进行操作的运算符,主要包括以下几个: - :取负,专门用于数值类型.实现了 std::ops::Neg. * :解引用.实现了 std::ops::Deref 或 std::ops::DerefMut. ! :取反.例如 !false 相当于 true.有意思的是,如果这个操作符对数字类型使用,会将其每

  • Rust字符串字面值的一些经验总结

    目录 前言 字符串字面值(String literals) Byte string literals 总结 前言 Rust 中有两种字符串,String 和 &str,其中 String 可动态分配.修改,内部实现可以理解为 Vec<u8>,而 &str 是一个类型为 &[u8] 的切片.这两种字符串都只能保存合法的 UTF-8 字符. 而对于非肉眼可辨识的 UTF-8 字符,则可以考虑使用如下类型: 文件路径有专用的 Path 和 PathBuf 类可用. 使用 Ve

  • c字符串,string对象,字符串字面值的区别详解

    一.字符串字面值字符串字面值是一串常量字符,字符串字面值常量用双引号括起来的零个或多个字符表示,为兼容C语言,C++中所有的字符串字面值都由编译器自动在末尾添加一个空字符.字符串没有变量名字,自身表示自身 复制代码 代码如下: "Hello World!" //simple string literal"" //empty string literal"\nCC\toptions\tfile.[cC]\n" //string literal us

  • 利用Rust编写一个简单的字符串时钟

    目录 1.简介 2.用到的知识点 2.1 取utc时间 2.2 图片变换为像素图案 2.3 字符方式显示当前时间 2.4 时间刷新 1.简介 用rust写的一个简单的练手的demo,一个字符串时钟,在终端用字符串方式显示当前时间.本质是对图片取灰度,然后每个像素按灰度门限用星号代替灰度值,就把图片变为由星号组成的字符型图案.把时间字符串的每个字符按照字母和数字图片的样式转换为字符,然后拼接字符图案就实现了字符时钟的效果. 主要用到的知识有:rust操作时间.字符串.vector,字符串和vect

  • C语言初识变量常量字符串转义符及注释方式简介

    目录 一:变量与常量 1.1:变量 1.1.1:变量的分类 1.1.2:变量的优先性 1.2:常量 1.2.1:#define定义 1.2.2:枚举常量 1.2.3:const修饰的常量 二:字符串介绍 三:转义字符的介绍 三:注释方式的介绍 一:变量与常量 1.1:变量 生活中有些值是可变的(比如年龄,体重,薪资). 下面我们举一个简单的例子表示变量的创建与使用. 1.1.1:变量的分类 局部变量 全局变量 这里主要介绍一下全局变量与局部变量作用域与生命周期. 作用域:通俗来讲,也就是一个变量

  • 2022最新Rust变量与数据类型讲解

    目录 变量与数据类型 变量和可变性 变量声明 变量命名 变量的可变性 变量遮蔽 常量 基本数据类型 整数类型 浮点数类型 布尔类型 字符类型 范围类型 复合数据类型 元组类型 数组类型 结构体类型 枚举类型 无参枚举类型 带参枚举类型 容器类型 Vec VecDeque HashMap 字符串 创建 修改 字符串的访问 字面量和运算符 字面量 运算符 变量与数据类型 常用的三大数据结构: 动态数组 映射 字符串 Rust标准库std::collections提供了4种通用的容器类型,其中包含8种

  • rust生命周期详解

    目录 rust生命周期 借用检查 函数中的生命周期 手动声明生命周期 结构体中的生命周期 生命周期消除 三条消除原则 生命周期约束 静态生命周期 rust生命周期 生命周期是rust中用来规定引用的有效作用域.在大多数时候,无需手动声明,因为编译器能够自动推导.当编译器无法自动推导出生命周期的时候,就需要我们手动标明生命周期.生命周期主要是为了避免悬垂引用. 借用检查 rust的编译器会使用借用检查器来检查我们程序的借用正确性.例如: #![allow(unused)] fn main() {

  • java 字符串内存分配的分析与总结(推荐)

    经常在网上各大版块都能看到对于java字符串运行时内存分配的探讨,形如:String a = "123",String b = new String("123"),这两种形式的字符串是存放在什么地方的呢,其实这两种形式的字符串字面值"123"本身在运行时既不是存放在栈上,也不是存放在堆上,他们是存放在方法区中的某个常量区,并且对于相同的字符串字面值在内存中只保留一份.下面我们将以实例来分析. 1.==运算符作用在两个字符串引用比较的两个案例: p

  • C++ 字符串的反转五种方法实例

    复制代码 代码如下: //通过不同的方法,实现对所输入字符串的反转,可以很好地复习巩固 C++ 基础知识/*分析过程: 假设要使传递的字符串为常量const字符串,这样操作更加灵活,可直接传递字符串字面值进行反转,常见的解决方法就是,定义一个新的与传递过来字符串长度 相等的字符数组,然后进行字符串拷贝,把str字符按从左到右放置到字符数组中,然后采用循环来对字符数组中字符反转*//*第一种,采用以上思路解法,传递为const类型C风格字符指针,返回为char*类型*///直接使用字符数组赋值ch

  • Python语法分析之字符串格式化

    前序 There should be one - and preferably only one - obvious way to do it. ---- the Zen of Python 意译:Python提倡用一种,而且最好是只有一种方法来完成一件事 虽然 Python 有以上的提倡,但却在字符串格式化方面,没有做到这一点. 字符串格式化 敲黑板,划重点:在 Python 中有至少三种常见方式实现字符串格式化: %-formatting 格式(Python2.6以前,推荐输出时使用) st

  • Python字符串对象实现原理详解

    在Python世界中将对象分为两种:一种是定长对象,比如整数,整数对象定义的时候就能确定它所占用的内存空间大小,另一种是变长对象,在对象定义时并不知道是多少,比如:str,list, set, dict等. >>> import sys >>> sys.getsizeof(1000) 28 >>> sys.getsizeof(2000) 28 >>> sys.getsizeof("python") 55 >&

随机推荐