Rust中模式匹配中的类型注释是什么?

7

我正在深入学习Rust,特别是优雅地处理错误,但是我在类型推断方面遇到了一些问题。

extern crate mysql;

use mysql as my;

fn main() {
    my_test();
}

fn my_test() -> Result<(), my::Error> {
    let pool = try!(my::Pool::new(""));
    let res = try!(pool.prep_exec("select 1 as count", ()));
    for rows in res {
        let row: my::Row = try!(rows);
        match row.take("count") {
            None => (),
            Some(i) => println!("{:?}", i),
        };
    }
    Ok(())
}

这导致了以下错误:

src/bin/main.rs:86:12: 86:13 错误:无法推断出关于 _ 的足够类型信息;需要类型注释或泛型参数绑定 [E0282]

不幸的是,该包中的文档经常使用 unwrap,这并没有帮助我。在 Haskell 中,我会做类似于 println!("{:?}", i :: i32) 的事情,但我无法弄清楚如何在 Rust 中实现它。我尝试了各种方法来转换 row.take,但都没有成功。如果有更符合惯用法的方式,我很乐意看到代码的多种结构。


1
请注意,这只是一个问题,因为您正在使用println!,它可以接受各种值。如果您在某些上下文中使用i值来限制类型(例如通过将其传递给函数),则可以推断出类型。 - Shepmaster
2个回答

11

看一下Row::take文档,我们可以看到两种类型的参数TI。类型I是从"count"参数中推断出来的,类型T用于返回类型。我们有两种选择指定返回类型,在方法调用中显式指定或隐式地指定为变量类型(就像您对row所做的那样):

fn my_test() -> Result<(), my::Error> {
    let pool = try!(my::Pool::new(""));
    let res = try!(pool.prep_exec("select 1 as count", ()));
    for rows in res {
        let mut row: my::Row = try!(rows);
        // specify type T explicitly, let type I to be inferred
        match row.take::<i32, _>("count") {
            None => (),
            Some(i) => println!("{:?}", i),
        };
        // or
        let s: Option<i32> = row.take("count");
    }
    Ok(())
}

类型说明 RFC提议使用一种类似于Haskell示例的语法来注释子表达式的类型,与原句保持一致。

3
类型可以在匹配模式中的Option<T>Result<T, E>变体上进行注释。
对于Option来说,
match row.take("count") {
    None => (),
    Some::<i32>(i) => println!("{:?}", i),
}

如果你的函数返回一个Result类型,

match row.take("count") {
    Err(e) => panic!("{:?}", e),
    Ok::<i32, _>(i) => println!("{:?}", i),
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接