将成对数组传递给函数时,未为类型“&A”实现特征
Trait is not implemented for the type `&A` when passing an array of pairs to a function
我正在尝试编写调用 Rust LMDB library (docs), and an example I'm working off of.
的函数 set
我这辈子都做不到。这是我目前的尝试:
fn main() {
let env = getenv("duperdb");
let dbhandle = get_dbhandle("", &env);
let txn = new_transaction(&env);
let vec = vec![("foo", "another text"), ("bar", "and another")];
set(&dbhandle, &env, &vec);
let reader = env.get_reader().unwrap();
let db = reader.bind(&dbhandle);
let note = db.get::<&str>("foo").unwrap();
println!("NOTE: {}", note);
}
其中 set
定义为:
pub fn set<A: ToMdbValue, B: ToMdbValue>(
handle: &DbHandle,
env: &Environment,
pairs: &Vec<(&A, &B)>) -> () {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(&id, ¬e).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}
这会出现以下错误:
src/db/wrapper.rs:28:20: 28:23 error: the trait `lmdb::traits::ToMdbValue` is not implemented for the type `&A` [E0277]
src/db/wrapper.rs:28 db.set(&id, ¬e).unwrap();
^~~
我也试过db.set(id, note).unwrap();
,但这次我得到:
src/main.rs:13:5: 13:8 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
src/main.rs:13 set(&dbhandle, &env, &vec);
^~~
src/main.rs:13:5: 13:8 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:13:5: 13:8 note: `str` does not have a constant size known at compile-time
src/main.rs:13:5: 13:8 note: required by `dupernote::db::wrapper::set`
src/main.rs:13:5: 13:8 error: the trait `lmdb_rs::traits::ToMdbValue` is not implemented for the type `str` [E0277]
src/main.rs:13 set(&dbhandle, &env, &vec);
^~~
我也试过类似的东西:
for (id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
但这也不起作用...我不完全明白为什么。 id
和 note
的类型不是 &str
,不是 str
吗?
这是您的问题的 MCVE:
trait Example {}
impl Example for i32 {}
fn library_call<T>(value: T)
where T: Example,
{}
fn user_call<T>(values: &[T])
where T: Example,
{
for i in values {
library_call(i);
}
}
fn main() {
let values = vec![1, 2, 3];
user_call(&values);
}
出现错误:
error: the trait `Example` is not implemented for the type `&T` [E0277]
library_call(i);
^~~~~~~~~~~~
错误消息完全正确 - Example
未 为 &T
实现,它只保证为 T
实现。 &T
和T
是不同的类型。
相反,您需要指出对泛型类型的引用实现了您需要的特征:
fn user_call<T>(values: &[T])
where for <'a> &'a T: Example,
然后您需要确保对具体类型的引用实际实现了特征:
impl<'a> Example for &'a i32 {}
或更广泛的版本:
impl<'a, T> Example for &'a T
where T: Example
{}
另见
给你一个错误的函数定义(如果我没看错文档的话):
fn set(&self, key: &ToMdbValue, value: &ToMdbValue) -> MdbResult<()>
key
必须是对特征对象的引用。您正在尝试传递对实现 ToMdbValue
的泛型类型的引用。
https://doc.rust-lang.org/book/trait-objects.html
我无法验证,但这应该有效:
pub fn set(handle: &DbHandle, env: &Environment, pairs: &Vec<(&ToMdbValue, &ToMdbValue)>) -> () {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}
其他:您可能想要使用盒装特征对象 Box<ToMdbValue>
。上面的 link 解释了它。您应该传递 &[YourType]
而不是 &Vec<[YourType]>
.
我设法让它工作了。我不确定这个解决方案的犹太洁食标准如何,但我会 post 它。
现在,在 main()
中,我执行以下操作(以 (int, string)
kv 对为例):
let k = 1;
let val = "hello there";
let vec = vec![(&k, &val)];
set(&dbhandle, &env, &vec);
我不得不单独声明它们,因为 vec![(&1, &"hello there")]
引发了 borrowed value does not live long enough
.
形式的错误
set
现在看起来像这样:
pub fn set<A, B>(handle: &DbHandle, env: &Environment, pairs: &Vec<(&A, &B)>)
-> ()
where A: ToMdbValue,
B: ToMdbValue {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}
我正在尝试编写调用 Rust LMDB library (docs), and an example I'm working off of.
的函数set
我这辈子都做不到。这是我目前的尝试:
fn main() {
let env = getenv("duperdb");
let dbhandle = get_dbhandle("", &env);
let txn = new_transaction(&env);
let vec = vec![("foo", "another text"), ("bar", "and another")];
set(&dbhandle, &env, &vec);
let reader = env.get_reader().unwrap();
let db = reader.bind(&dbhandle);
let note = db.get::<&str>("foo").unwrap();
println!("NOTE: {}", note);
}
其中 set
定义为:
pub fn set<A: ToMdbValue, B: ToMdbValue>(
handle: &DbHandle,
env: &Environment,
pairs: &Vec<(&A, &B)>) -> () {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(&id, ¬e).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}
这会出现以下错误:
src/db/wrapper.rs:28:20: 28:23 error: the trait `lmdb::traits::ToMdbValue` is not implemented for the type `&A` [E0277]
src/db/wrapper.rs:28 db.set(&id, ¬e).unwrap();
^~~
我也试过db.set(id, note).unwrap();
,但这次我得到:
src/main.rs:13:5: 13:8 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
src/main.rs:13 set(&dbhandle, &env, &vec);
^~~
src/main.rs:13:5: 13:8 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:13:5: 13:8 note: `str` does not have a constant size known at compile-time
src/main.rs:13:5: 13:8 note: required by `dupernote::db::wrapper::set`
src/main.rs:13:5: 13:8 error: the trait `lmdb_rs::traits::ToMdbValue` is not implemented for the type `str` [E0277]
src/main.rs:13 set(&dbhandle, &env, &vec);
^~~
我也试过类似的东西:
for (id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
但这也不起作用...我不完全明白为什么。 id
和 note
的类型不是 &str
,不是 str
吗?
这是您的问题的 MCVE:
trait Example {}
impl Example for i32 {}
fn library_call<T>(value: T)
where T: Example,
{}
fn user_call<T>(values: &[T])
where T: Example,
{
for i in values {
library_call(i);
}
}
fn main() {
let values = vec![1, 2, 3];
user_call(&values);
}
出现错误:
error: the trait `Example` is not implemented for the type `&T` [E0277]
library_call(i);
^~~~~~~~~~~~
错误消息完全正确 - Example
未 为 &T
实现,它只保证为 T
实现。 &T
和T
是不同的类型。
相反,您需要指出对泛型类型的引用实现了您需要的特征:
fn user_call<T>(values: &[T])
where for <'a> &'a T: Example,
然后您需要确保对具体类型的引用实际实现了特征:
impl<'a> Example for &'a i32 {}
或更广泛的版本:
impl<'a, T> Example for &'a T
where T: Example
{}
另见
给你一个错误的函数定义(如果我没看错文档的话):
fn set(&self, key: &ToMdbValue, value: &ToMdbValue) -> MdbResult<()>
key
必须是对特征对象的引用。您正在尝试传递对实现 ToMdbValue
的泛型类型的引用。
https://doc.rust-lang.org/book/trait-objects.html
我无法验证,但这应该有效:
pub fn set(handle: &DbHandle, env: &Environment, pairs: &Vec<(&ToMdbValue, &ToMdbValue)>) -> () {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}
其他:您可能想要使用盒装特征对象 Box<ToMdbValue>
。上面的 link 解释了它。您应该传递 &[YourType]
而不是 &Vec<[YourType]>
.
我设法让它工作了。我不确定这个解决方案的犹太洁食标准如何,但我会 post 它。
现在,在 main()
中,我执行以下操作(以 (int, string)
kv 对为例):
let k = 1;
let val = "hello there";
let vec = vec![(&k, &val)];
set(&dbhandle, &env, &vec);
我不得不单独声明它们,因为 vec![(&1, &"hello there")]
引发了 borrowed value does not live long enough
.
set
现在看起来像这样:
pub fn set<A, B>(handle: &DbHandle, env: &Environment, pairs: &Vec<(&A, &B)>)
-> ()
where A: ToMdbValue,
B: ToMdbValue {
let txn = new_transaction(&env);
{
let db = txn.bind(&handle);
for &(id, note) in pairs.iter() {
db.set(id, note).unwrap();
}
}
match txn.commit() {
Err(_) => panic!("Failed to commit!"),
Ok(_) => (),
}
}