Rust Deduped Cow HashSet
Rust Deduped Cow HashSet
想要存储大量字节数组并打算用 AHashMap<Vec<u8>>
来做到这一点并使用 Cow 从中借用并仅在需要时写入,这也应该导致它被重复删除。然而,到目前为止我的尝试都是徒劳的:
#![feature(hash_set_entry)]
use std::borrow::{Borrow, Cow, ToOwned};
use std::hash::Hash;
use ahash::AHashSet;
#[derive(Debug)]
struct CipherText<'a> {
ciphertext: Cow<'a, Vec<u8>>,
ciphers: Vec<Cipher<'a>>,
}
#[derive(Debug)]
struct Cipher<'a> {
cipher_id: Cow<'a, Vec<u8>>,
keys: Vec<Cow<'a, Vec<u8>>>,
}
fn main() {
let mut string_table: AHashSet<Vec<u8>> = vec![
"Hello World!".as_bytes().to_vec(),
"atbash".as_bytes().to_vec(),
"caesar_decrypt".as_bytes().to_vec(),
"5".as_bytes().to_vec(),
]
.into_iter()
.collect();
let mut ciphertexts: Vec<CipherText> = vec![
CipherText {
ciphertext: Cow::Borrowed(
string_table
.get(&"Hello World!".as_bytes().to_vec())
.unwrap(),
),
ciphers: vec![Cipher {
cipher_id: Cow::Borrowed(string_table.get(&"atbash".as_bytes().to_vec()).unwrap()),
keys: vec![],
}],
},
CipherText {
ciphertext: Cow::Borrowed(
string_table
.get(&"Hello World!".as_bytes().to_vec())
.unwrap(),
),
ciphers: vec![Cipher {
cipher_id: Cow::Borrowed(
string_table
.get(&"caesar_decrypt".as_bytes().to_vec())
.unwrap(),
),
keys: vec![Cow::Borrowed(
string_table.get(&"5".as_bytes().to_vec()).unwrap(),
)],
}],
},
];
string_table.insert("TEST".as_bytes().to_vec());
string_table.insert("TEST2".as_bytes().to_vec());
ciphertexts[0].ciphertext = Cow::Borrowed(
&string_table.get_or_insert_owned(&"Goodbye Cruel World...".as_bytes().to_vec()),
);
}
TEST行和密文[0]行错误如下
error[E0502]: cannot borrow `string_table` as mutable because it is also borrowed as immutable
--> src/main.rs:61:5
|
33 | string_table
| ------------ immutable borrow occurs here
...
61 | string_table.insert("TEST".as_bytes().to_vec());
| ^^^^^^^^^^^^ mutable borrow occurs here
...
64 | ciphertexts[0].ciphertext = Cow::Borrowed(
| ----------- immutable borrow later used here
我的目标是让所有字节数组仅作为引用然后克隆,添加到 string_table 并在我更改它时引用它。此数据将以自定义二进制格式存储,这是编写序列化器和反序列化器过程的开始。希望这一切都有意义!
当 CipherText
持有对它的引用时,您不能改变 string_table
。这只是 Rust 的核心不变量之一。所以你不能使用Cow
。解决它的典型方法通常是:
使用 indexes/keys 引用其他结构,不幸的是,在这种情况下我看不到这样做的好方法。
使用Rc
s使得密文和table共享所有权的字节。这确实意味着密文可以独立存在,但您始终可以使用 table 作为中间人在使用它们之前通过明智地使用 get_or_insert
.
来删除元素。
#![feature(hash_set_entry)]
use std::rc::Rc;
use ahash::AHashSet;
#[derive(Debug)]
struct CipherText {
ciphertext: Rc<Vec<u8>>,
ciphers: Vec<Cipher>,
}
#[derive(Debug)]
struct Cipher {
cipher_id: Rc<Vec<u8>>,
keys: Vec<Rc<Vec<u8>>>,
}
fn main() {
let mut string_table: AHashSet<Rc<Vec<u8>>> = vec![
Rc::new("Hello World!".as_bytes().to_vec()),
Rc::new("atbash".as_bytes().to_vec()),
Rc::new("caesar_decrypt".as_bytes().to_vec()),
Rc::new("5".as_bytes().to_vec()),
]
.into_iter()
.collect();
let mut ciphertexts: Vec<CipherText> = vec![
CipherText {
ciphertext: string_table
.get_or_insert(Rc::new("Hello World!".as_bytes().to_vec()))
.clone(),
ciphers: vec![Cipher {
cipher_id: string_table
.get_or_insert(Rc::new("atbash".as_bytes().to_vec()))
.clone(),
keys: vec![],
}],
},
CipherText {
ciphertext: string_table
.get_or_insert(Rc::new("Hello World!".as_bytes().to_vec()))
.clone(),
ciphers: vec![Cipher {
cipher_id: string_table
.get_or_insert(Rc::new("caesar_decrypt".as_bytes().to_vec()))
.clone(),
keys: vec![string_table
.get_or_insert(Rc::new("5".as_bytes().to_vec()))
.clone()],
}],
},
];
string_table.insert(Rc::new("TEST".as_bytes().to_vec()));
string_table.insert(Rc::new("TEST2".as_bytes().to_vec()));
ciphertexts[0].ciphertext = string_table
.get_or_insert(Rc::new("Goodbye Cruel World...".as_bytes().to_vec()))
.clone();
}
这将与Cow
具有相同的效果,Rc
拥有的元素是immutable,因此必须创建一个新元素来进行更改。
想要存储大量字节数组并打算用 AHashMap<Vec<u8>>
来做到这一点并使用 Cow 从中借用并仅在需要时写入,这也应该导致它被重复删除。然而,到目前为止我的尝试都是徒劳的:
#![feature(hash_set_entry)]
use std::borrow::{Borrow, Cow, ToOwned};
use std::hash::Hash;
use ahash::AHashSet;
#[derive(Debug)]
struct CipherText<'a> {
ciphertext: Cow<'a, Vec<u8>>,
ciphers: Vec<Cipher<'a>>,
}
#[derive(Debug)]
struct Cipher<'a> {
cipher_id: Cow<'a, Vec<u8>>,
keys: Vec<Cow<'a, Vec<u8>>>,
}
fn main() {
let mut string_table: AHashSet<Vec<u8>> = vec![
"Hello World!".as_bytes().to_vec(),
"atbash".as_bytes().to_vec(),
"caesar_decrypt".as_bytes().to_vec(),
"5".as_bytes().to_vec(),
]
.into_iter()
.collect();
let mut ciphertexts: Vec<CipherText> = vec![
CipherText {
ciphertext: Cow::Borrowed(
string_table
.get(&"Hello World!".as_bytes().to_vec())
.unwrap(),
),
ciphers: vec![Cipher {
cipher_id: Cow::Borrowed(string_table.get(&"atbash".as_bytes().to_vec()).unwrap()),
keys: vec![],
}],
},
CipherText {
ciphertext: Cow::Borrowed(
string_table
.get(&"Hello World!".as_bytes().to_vec())
.unwrap(),
),
ciphers: vec![Cipher {
cipher_id: Cow::Borrowed(
string_table
.get(&"caesar_decrypt".as_bytes().to_vec())
.unwrap(),
),
keys: vec![Cow::Borrowed(
string_table.get(&"5".as_bytes().to_vec()).unwrap(),
)],
}],
},
];
string_table.insert("TEST".as_bytes().to_vec());
string_table.insert("TEST2".as_bytes().to_vec());
ciphertexts[0].ciphertext = Cow::Borrowed(
&string_table.get_or_insert_owned(&"Goodbye Cruel World...".as_bytes().to_vec()),
);
}
TEST行和密文[0]行错误如下
error[E0502]: cannot borrow `string_table` as mutable because it is also borrowed as immutable
--> src/main.rs:61:5
|
33 | string_table
| ------------ immutable borrow occurs here
...
61 | string_table.insert("TEST".as_bytes().to_vec());
| ^^^^^^^^^^^^ mutable borrow occurs here
...
64 | ciphertexts[0].ciphertext = Cow::Borrowed(
| ----------- immutable borrow later used here
我的目标是让所有字节数组仅作为引用然后克隆,添加到 string_table 并在我更改它时引用它。此数据将以自定义二进制格式存储,这是编写序列化器和反序列化器过程的开始。希望这一切都有意义!
当 CipherText
持有对它的引用时,您不能改变 string_table
。这只是 Rust 的核心不变量之一。所以你不能使用Cow
。解决它的典型方法通常是:
使用 indexes/keys 引用其他结构,不幸的是,在这种情况下我看不到这样做的好方法。
使用
来删除元素。Rc
s使得密文和table共享所有权的字节。这确实意味着密文可以独立存在,但您始终可以使用 table 作为中间人在使用它们之前通过明智地使用get_or_insert
.#![feature(hash_set_entry)] use std::rc::Rc; use ahash::AHashSet; #[derive(Debug)] struct CipherText { ciphertext: Rc<Vec<u8>>, ciphers: Vec<Cipher>, } #[derive(Debug)] struct Cipher { cipher_id: Rc<Vec<u8>>, keys: Vec<Rc<Vec<u8>>>, } fn main() { let mut string_table: AHashSet<Rc<Vec<u8>>> = vec![ Rc::new("Hello World!".as_bytes().to_vec()), Rc::new("atbash".as_bytes().to_vec()), Rc::new("caesar_decrypt".as_bytes().to_vec()), Rc::new("5".as_bytes().to_vec()), ] .into_iter() .collect(); let mut ciphertexts: Vec<CipherText> = vec![ CipherText { ciphertext: string_table .get_or_insert(Rc::new("Hello World!".as_bytes().to_vec())) .clone(), ciphers: vec![Cipher { cipher_id: string_table .get_or_insert(Rc::new("atbash".as_bytes().to_vec())) .clone(), keys: vec![], }], }, CipherText { ciphertext: string_table .get_or_insert(Rc::new("Hello World!".as_bytes().to_vec())) .clone(), ciphers: vec![Cipher { cipher_id: string_table .get_or_insert(Rc::new("caesar_decrypt".as_bytes().to_vec())) .clone(), keys: vec![string_table .get_or_insert(Rc::new("5".as_bytes().to_vec())) .clone()], }], }, ]; string_table.insert(Rc::new("TEST".as_bytes().to_vec())); string_table.insert(Rc::new("TEST2".as_bytes().to_vec())); ciphertexts[0].ciphertext = string_table .get_or_insert(Rc::new("Goodbye Cruel World...".as_bytes().to_vec())) .clone(); }
这将与
Cow
具有相同的效果,Rc
拥有的元素是immutable,因此必须创建一个新元素来进行更改。