简体   繁体   English

预期的约束寿命参数,找到的混凝土寿命[E0271]

[英]Expected bound lifetime parameter, found concrete lifetime [E0271]

While the code below is an early prototype and not to be taken too seriously concerning how I implement protocol buffers at this stage, I fail to understand what the error message rust compilers blesses me with refers to. 尽管下面的代码是早期的原型,在现阶段如何实现协议缓冲区时不要太在意,但我无法理解rust编译器祝福我的错误消息。

src\\main.rs:89:9: 89:36 error: type mismatch resolving for<'r> <[closure src\\ma in.rs:75:33: 88:10] as core::ops::FnOnce<(u32, gpb::definitions::WireType, &'r collections::vec::Vec<u8>, usize)>>::Output == usize : expected bound lifetime parameter , found concrete lifetime [E0271] src\\main.rs:89 gpb::decoding::read_message( source, field_handler ); src \\ main.rs:89:9:89:36错误:类型不匹配解析for<'r> <[closure src\\ma in.rs:75:33: 88:10] as core::ops::FnOnce<(u32, gpb::definitions::WireType, &'r collections::vec::Vec<u8>, usize)>>::Output == usize :预期的绑定寿命参数,找到了具体寿命[E0271] src \\ main .rs:89 gpb :: decoding :: read_message(source,field_handler);

Even after reading the 3 documentation chapters on lifetimes et. 即使在阅读了3个有关有效期等的文档章节之后, al. I did not come across the term "concrete lifetime" and thus have trouble figuring out what code this error relates to. 我没有遇到过“具体寿命”一词,因此很难弄清楚该错误与什么代码有关。 The closure itself, one or multiple arguments, the return code? 闭包本身,一个或多个参数,返回码? The passing of the closure to read_message() ? 将闭包传递给read_message()吗? ... ...

main.rs snippet 主代码段

fn from_gpb( source : &Vec<u8>) -> TimeMessage {
    fn init_vec_u64( count : usize, init_value : u64) -> Vec<u64> {
        let mut result = Vec::<u64>::with_capacity(count);
        for i in 0..count {
            result.push(init_value);
        }
        result
    }
    let mut message_id : u32 = 0;
    let mut times_sec  = init_vec_u64(4,0u64);
    let mut times_usec = init_vec_u64(4,0u64);
    let mut max_time_index = 0;
    let mut time_index = | index | { if max_time_index < index { max_time_index = index;}};
    let mut field_handler = |tag,wire_type,source,position| -> usize {
        match (tag,wire_type) {
            (1u32,gpb::definitions::WireType::Varint) => {let (v,p) = gpb::decoding::read_varint32(source,position); message_id = v; p},
            (2u32,gpb::definitions::WireType::Fixed64) => {let (sec,p) = gpb::decoding::read_fixed64(source,position); times_sec[0] = sec; time_index(0); p},
            (3u32,gpb::definitions::WireType::Fixed64) => {let (usec,p) = gpb::decoding::read_fixed64(source,position); times_usec[0] = usec; time_index(0); p},
            (4u32,gpb::definitions::WireType::Fixed64) => {let (sec,p) = gpb::decoding::read_fixed64(source,position); times_sec[1] = sec; time_index(1);p},
            (5u32,gpb::definitions::WireType::Fixed64) => {let (usec,p) = gpb::decoding::read_fixed64(source,position); times_usec[1] = usec; time_index(1);p},
            (6u32,gpb::definitions::WireType::Fixed64) => {let (sec,p) = gpb::decoding::read_fixed64(source,position); times_sec[2] = sec; time_index(2);p},
            (7u32,gpb::definitions::WireType::Fixed64) => {let (usec,p) = gpb::decoding::read_fixed64(source,position); times_usec[2] = usec; time_index(2); p},
            (8u32,gpb::definitions::WireType::Fixed64) => {let (sec,p) = gpb::decoding::read_fixed64(source,position); times_sec[3] = sec; time_index(3); p},
            (9u32,gpb::definitions::WireType::Fixed64) => {let (usec,p) = gpb::decoding::read_fixed64(source,position); times_usec[3] = usec; time_index(3); p},
            (_,_) => panic!("Invalid field tag/wire_type combination!") // TODO: change the panic to a gpb::decoding::skip(..) call.
        }
    };
    gpb::decoding::read_message( source, field_handler );
    let mut make_times = || -> Vec<prectime::PrecTime> {
        let time_count = max_time_index+1;
        let mut times = Vec::<prectime::PrecTime>::with_capacity(time_count);
        times_sec.truncate(time_count);
        times_usec.truncate(time_count);
        for i in 0..time_count {
            times.push(prectime::PrecTime { sec : times_sec[i], usec : times_usec[i]});
        }
        times               
    };
    TimeMessage { id : message_id, times : make_times() }    
}

gpb.rs snippet gpb.rs代码段

pub fn read_message<F>( source : &Vec<u8>, field_handler : F) where F: Fn(u32,super::definitions::WireType, &Vec<u8>, usize) -> usize {
    let mut cursor = 0;
    while cursor < source.len() {
        let (tag_and_wire_type, position) = read_varint32( source, cursor );
        let wt = super::definitions::wire_type_from_value( tag_and_wire_type & 0x07u32 );
        let tag = (tag_and_wire_type >> 3);
        let new_pos = field_handler(tag,wt, source,position);
        cursor = new_pos;
    }
}

Summary of what the code does: 代码摘要:

  • define field_handler function 定义field_handler函数
  • read_message(data,field_handler) -> calls n times: field_handler read_message(data,field_handler)->调用n次:field_handler
  • exit scope. 退出范围。

As anything (the closure, the calls, the vectors, the field_handler writes in from_gpb() context,...) is defined inside from_gpb() function, I simply do not understand how the lifetime could become an issue. 由于在from_gpb()函数中定义了任何内容(闭包,调用,向量,field_handler在from_gpb()上下文中写的...),所以我根本不理解生存期如何成为问题。 All information about lifetimes should be available to the compiler. 有关生存期的所有信息应可供编译器使用。

First thing's first, if you want a quick answer, you should put some effort into writing a minimal, compilable example so that people don't have to guess whether or not a potential solution is going to work or not. 首先,如果要快速回答,您应该花一些精力编写一个最小的可编译示例,这样人们就不必猜测潜在的解决方案是否会起作用。 Like this: 像这样:

enum WireType {}

fn from_gpb(source: &Vec<u8>) {
    let mut field_handler = |tag, wire_type, source, position| -> usize {
        let tag: u32 = tag;
        let wire_type: WireType = wire_type;
        let source: &Vec<u8> = source;
        let position: usize = position;
        panic!();
    };
    read_message(source, field_handler);
}

fn read_message<F>(source: &Vec<u8>, field_handler: F)
where
    F: Fn(u32, WireType, &Vec<u8>, usize) -> usize,
{
    panic!();
}

The rest of this answer is based on the above which appears to replicate your problem: 该答案的其余部分基于上述内容, 似乎可以复制您的问题:

error[E0631]: type mismatch in closure arguments
  --> src/lib.rs:11:5
   |
4  |     let mut field_handler = |tag, wire_type, source, position| -> usize {
   |                             ------------------------------------------- found signature of `fn(u32, WireType, &std::vec::Vec<u8>, usize) -> _`
...
11 |     read_message(source, field_handler);
   |     ^^^^^^^^^^^^ expected signature of `for<'r> fn(u32, WireType, &'r std::vec::Vec<u8>, usize) -> _`
   |
note: required by `read_message`
  --> src/lib.rs:14:1
   |
14 | / fn read_message<F>(source: &Vec<u8>, field_handler: F)
15 | | where
16 | |     F: Fn(u32, WireType, &Vec<u8>, usize) -> usize,
17 | | {
18 | |     panic!();
19 | | }
   | |_^

error[E0271]: type mismatch resolving `for<'r> <[closure@src/lib.rs:4:29: 10:6] as std::ops::FnOnce<(u32, WireType, &'r std::vec::Vec<u8>, usize)>>::Output == usize`
  --> src/lib.rs:11:5
   |
11 |     read_message(source, field_handler);
   |     ^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime
   |
note: required by `read_message`
  --> src/lib.rs:14:1
   |
14 | / fn read_message<F>(source: &Vec<u8>, field_handler: F)
15 | | where
16 | |     F: Fn(u32, WireType, &Vec<u8>, usize) -> usize,
17 | | {
18 | |     panic!();
19 | | }
   | |_^

The simplest thing to do is to allow the compiler to properly infer the closure type: 最简单的操作是允许编译器正确推断闭包类型:

fn from_gpb_closure_inference(source: &Vec<u8>) {
    read_message(source, |tag, wire_type, source, position| -> usize {
        let tag: u32 = tag;
        let wire_type: WireType = wire_type;
        let source: &Vec<u8> = source;
        let position: usize = position;
        panic!();
    });
}

Closure inference only really works properly when the closure is provided directly as an argument to a function. 仅当直接将闭包作为函数的参数提供时,闭包推断才真正正确地起作用。 In theory, the two should be equivalent, but they aren't . 从理论上讲,这两个值应该相等,但不是相同的

The other thing you can do is kind-of trick the compiler into doing the inference without actually using the closure: 您可以做的另一件事是在不实际使用闭包的情况下欺骗编译器进行推断:

fn constrain_handler<F>(f: F) -> F
where
    F: Fn(u32, WireType, &Vec<u8>, usize) -> usize,
{
    f
}

fn from_gpb_constrain(source: &Vec<u8>) {
    let mut field_handler = constrain_handler(|tag, wire_type, source, position| -> usize {
        let tag: u32 = tag;
        let wire_type: WireType = wire_type;
        let source: &Vec<u8> = source;
        let position: usize = position;
        panic!();
    });
    read_message(source, field_handler);
}

In this case, the constrain_handler function is just getting the compiler to nail down the type of the closure, allowing it to be used (or not) later on. 在这种情况下, constrain_handler函数只是让编译器确定闭包的类型,以便以后使用(或不使用)它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 函数引用:预期的约束生命周期参数,找到具体的生命周期[E0271] - Function references: expected bound lifetime parameter , found concrete lifetime [E0271] 预期的约束寿命参数,找到具体的寿命 - Expected bound lifetime parameter, found concrete lifetime 如何解决:预期的混凝土寿命,但找到了约束寿命参数 - How to fix: expected concrete lifetime, but found bound lifetime parameter StreamExt.scan() 方法上的“预期绑定生命周期参数,找到具体生命周期” - “expected bound lifetime parameter, found concrete lifetime” on StreamExt .scan() method 锈蚀寿命误差预期具体寿命但发现约束寿命 - Rust lifetime error expected concrete lifetime but found bound lifetime 预期绑定生命周期参数,在尝试传递选项时找到具体生命周期<fnonce></fnonce> - Expected bound lifetime parameter, found concrete lifetime when trying to pass an Option<FnOnce> 预期的混凝土寿命,在结构中存储fn时找到约束寿命参数 - Expected concrete lifetime, found bound lifetime parameter when storing a fn in a struct 从闭包填充集合时,键入不匹配“绑定生命周期参数”与“具体生命周期” - Type mismatch “bound lifetime parameter” vs “concrete lifetime” when filling a collection from a closure 当使用参数的生命周期作为特征参数时,“预期的关联类型,找到`u32`” - “Expected associated type, found `u32`” when using the lifetime of a parameter as trait parameter in where bound 为什么此特性/实现不兼容-约束寿命与具体寿命 - Why is this trait/implementation incompatible - bound lifetime vs concrete lifetime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM