0

我正在尝试编写set调用 Rust LMDB 库文档)的函数,以及我正在处理的一个示例

我这辈子都做不到。这是我目前的尝试:

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, &note).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, &note).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();
    }

但这也不起作用......我不完全明白为什么。没有idnote有类型&str,不是str吗?

4

3 回答 3

1

给你一个错误的函数的定义(如果我正在阅读正确的文档):

fn set(&self, key: &ToMdbValue, value: &ToMdbValue) -> MdbResult<()>

key必须是对 trait 对象的引用。您正在尝试传递对泛型类型 implmementing 的引用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>。上面的链接解释了它。你应该通过 a&[YourType]而不是&Vec<[YourType]>.

于 2016-03-15T17:01:05.867 回答
1

这是您的问题的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为实现,它只保证为 实现。并且是不同的类型&TT&TT

相反,您需要指出对泛型类型的引用实现了您需要的特征:

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
{}

另请参阅我何时不应该为引用该特征的实现者实现特征?

于 2016-03-15T16:54:05.797 回答
1

我设法让它工作。我不确定这个解决方案有多洁净,但我会发布它。

所以现在,在 中,我执行以下操作(以kv 对main()为例):(int, string)

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(_) => (),
    }
}
于 2016-03-15T20:05:14.440 回答