这个问题的第一部分可能很常见,已经有足够的代码示例来解释如何生成一个随机的字母数字字符串。我使用的代码段来自这里。
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect();
println!("{}", rand_string);
}
这段代码无法编译,(注:我在使用夜间版本):
error[E0277]: a value of type `String` cannot be built from an iterator over elements of type `u8`
--> src/main.rs:8:10
|
8 | .collect();
| ^^^^^^^ value of type `String` cannot be built from `std::iter::Iterator<Item=u8>`
|
= help: the trait `FromIterator<u8>` is not implemented for `String`
好的,生成的元素是u8
类型的。因此我猜这是u8
类型的数组或向量:
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let r = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect::<Vec<_>>();
let s = String::from_utf8_lossy(&r);
println!("{}", s);
}
这段代码已经编译成功并且可以正常运行!
2dCsTqoNUR1f0EzRV60IiuHlaM4TfK
一切都好,除了我想问问有人能解释一下类型方面到底发生了什么,以及如何进行优化。
问题
.sample_iter(&Alphanumeric)
生成的是u8
而不是char
吗?- 我该如何避免第二个变量
s
,直接将u8
解释为一个 utf-8 字符?我猜内存中的表示方式没有任何改变吧? - 这些字符串的长度应该始终为 30,我该如何优化掉
Vec
的堆分配?此外,它们实际上可以是char[]
而不是String
。
Vec<u8>
而不是Vec<char>
的原因:char
总是占用 4 个字节,这意味着对于任何 ASCII 字母数字序列,存储字符将浪费三倍的内存。 - Ivan C