Rust中的“()”类型是什么?

piztneat  于 2023-10-20  发布在  其他
关注(0)|答案(4)|浏览(157)

作为学习Rust的一个简单练习,我决定实现一个简单的二进制搜索:

pub fn binary_search(arr: &[i32], key: i32) -> usize {
    let min: usize = 0;
    let max: usize = arr.len();
    while max >= min {
        let mid: usize = (max - min) / 2 as usize;
        if key == arr[mid] {
            mid as usize
        }

        if key < arr[mid] {
            min = mid + 1;
            continue;
        }

        max = mid - 1;
    }
    -1 as usize
}

#[cfg(test)]
mod tests {
    use super::binary_search;

    #[test]
    fn binary_search_works() {
        let arr: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
        let index: usize = binary_search(&arr, 2);
        assert_eq!(1, index);
    }
}

在构建时,我得到了这个我不理解的错误。什么是()类型?变量mid始终是usize,但即使使用as强制转换,我也会得到以下编译错误:

error: mismatched types [E0308]
            mid as usize
            ^~~~~~~~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `()`
note:    found type `usize`
e0uiprwp

e0uiprwp1#

()unit typesingleton type:它具有单个值,也表示为()
我个人认为它是一个0元素的元组。
在C或C++使用void(没有值)来表示函数的返回类型时,Rust使用()。这对元编程来说要好得多,因为()是一个接受值的常规类型,可以被变异、借用等。
关于您的具体代码示例:

if key == arr[mid] {
    mid as usize
}

是一个()类型的表达式(因为没有else分支),但你试图让if块计算为mid as usize,而mid as usize的类型是usize,因此编译器会注意到不匹配。
在这里使用return

if key == arr[mid] {
    return mid as usize;
}
roqulrg3

roqulrg32#

()是 * 单位类型 *,类似于其他语言中的void返回类型。
你在这里得到它:

if key == arr[mid] {
    mid as usize
}

Rust期望if expression返回(),但你返回的是usize。由于Rust中几乎所有的东西都是表达式,所以你可以 * 通常 * 隐式返回,就像你在这里尝试的那样,但在这个特定的情况下,你不能,因为if表达式不是while表达式中的唯一表达式。您可以通过使用return mid as usize;来解决直接问题。

t40tm48m

t40tm48m3#

这里有两个问题
1.返回类型()
1.提前从函数返回
关于您的具体代码示例:

if key == arr[mid] {
    mid as usize
}

通过在这个表达式的末尾省略字符串,你试图返回一个类型()
“为什么?”你可能会问。See this answer,但长话短说,它通过避免if语句中的Option类型使核心语言更简单。

24 | |         };
   | |_________^ expected `()`, found integer
   |
   = note: `if` expressions without `else` evaluate to `()`
   = help: consider adding an `else` block that evaluates to the expected type

For more information about this error, try `rustc --explain E0317`.

即使在这里添加一个else语句也没有帮助,因为你要做的是提前从函数中获取return,而不是返回表达式的值。记住,任何不以字符串结尾的表达式{ expression }都将其值 * 返回到周围的上下文 *,在本例中,上下文是函数的主体。
使用return会导致函数提前返回,这正是您想要的。

if key == arr[mid] {
    return mid as usize;
}

请注意,在函数末尾不需要return函数的原因是

-1 as usize

是因为它 * 正在 * 返回到周围的上下文:在这个例子中是函数被调用的地方。

63lcw9qa

63lcw9qa4#

我试着运行你的代码,但它似乎不工作。单元测试在检查所有值时可能会永远运行,例如:
assert_eq!(1, index); assert_eq!(2, index); assert_eq!(3, index);...assert_eq!(8, index);
你确定这个算法编码正确吗?更不用说关于letlet mut等的警告了。

相关问题