Recursion 递归函数if语句与Rust中的类型不匹配

Recursion 递归函数if语句与Rust中的类型不匹配,recursion,types,rust,Recursion,Types,Rust,我不知道如何重写此函数以满足类型检查器的要求。我假设这是因为我将返回类型设置为bool,并且有一个返回函数调用?这里的问题是Rust将if/else if/else if块作为返回值进行计算,因为它缺少else子句,而不计算为任何值的语句的类型为()。顺便说一句,您提供的代码确实详尽地涵盖了所有可能性(切片当前索引处的项等于、小于或大于目标),但编译器不知道这一点,除非您在末尾给它一个else子句: src/main.rs:33:5: 39:6 error: mismatched types [

我不知道如何重写此函数以满足类型检查器的要求。我假设这是因为我将返回类型设置为bool,并且有一个返回函数调用?

这里的问题是Rust将
if/else if/else if
块作为返回值进行计算,因为它缺少
else
子句,而不计算为任何值的语句的类型为
()
。顺便说一句,您提供的代码确实详尽地涵盖了所有可能性(切片当前索引处的项等于、小于或大于目标),但编译器不知道这一点,除非您在末尾给它一个
else
子句:

src/main.rs:33:5: 39:6 error: mismatched types [E0308]
src/main.rs:33     if target == list[guess] {
                   ^
src/main.rs:33:5: 39:6 help: run `rustc --explain E0308` to see a detailed explanation
src/main.rs:33:5: 39:6 note: expected type `bool`
src/main.rs:33:5: 39:6 note:    found type `()`
error: aborting due to previous error
fn递归二进制搜索(列表:&[T],目标:T)->bool{
如果list.len()小于1{
返回false;
}
让guess=list.len()/2;
如果目标==列表[猜测]{
返回true;
}否则,如果列表[猜测]>目标{
返回递归的二进制搜索(&list[0..guess],目标);
}否则{
返回递归的二进制搜索(&list[guess..list.len()],目标);
}
}
PS:这个函数不需要可变引用,所以我建议使用上面代码中的常规引用

编辑:对于子孙后代,下面是相同的代码,没有显式返回:

fn recursive_binary_search<T: Ord + Eq>(list: &[T], target: T) -> bool {
    if list.len() < 1 {
        return false;
    }
    let guess = list.len() / 2;
    if target == list[guess] {
        return true;
    } else if list[guess] > target {
        return recursive_binary_search(&list[0..guess], target);
    } else {
        return recursive_binary_search(&list[guess..list.len()], target);
    }
}
fn recursive_binary_search<T: Ord>(list: &[T], target: T) -> bool {
    if list.len() < 1 {
        return false;
    }
    let guess = list.len() / 2;
    if target == list[guess] {
        true
    } else if list[guess] > target {
        recursive_binary_search(&list[0..guess], target)
    } else {
        recursive_binary_search(&list[guess..list.len()], target)
    }
}
fn递归二进制搜索(列表:&[T],目标:T)->bool{
如果list.len()小于1{
返回false;
}
让guess=list.len()/2;
如果目标==列表[猜测]{
真的
}否则,如果列表[猜测]>目标{
递归\u二进制\u搜索(&list[0..guess],目标)
}否则{
递归二进制搜索(&list[guess..list.len()],目标)
}
}
解释了问题:如果
的结果类型是
()
,则返回的是
而不是
bool

这里有几种更习惯地编写代码的方法:

我首先用隐式返回编写它:

fn recursive_binary_search<T: Ord + Eq>(list: &[T], target: T) -> bool {
    if list.len() < 1 {
        return false;
    }
    let guess = list.len() / 2;
    if target == list[guess] {
        return true;
    } else if list[guess] > target {
        return recursive_binary_search(&list[0..guess], target);
    } else {
        return recursive_binary_search(&list[guess..list.len()], target);
    }
}
fn recursive_binary_search<T: Ord>(list: &[T], target: T) -> bool {
    if list.len() < 1 {
        return false;
    }
    let guess = list.len() / 2;
    if target == list[guess] {
        true
    } else if list[guess] > target {
        recursive_binary_search(&list[0..guess], target)
    } else {
        recursive_binary_search(&list[guess..list.len()], target)
    }
}
您还可以删除范围的开始部分和结束部分,并对guard子句使用
is_empty

如果搜索的值大于最大值,则会出现堆栈溢出问题。。。重复出现时,您需要忽略轴:

use std::cmp::Ordering;

fn recursive_binary_search<T: Ord + Eq>(list: &[T], target: T) -> bool {
    if list.is_empty() {
        return false;
    }

    let guess = list.len() / 2;

    match target.cmp(&list[guess]) {
        Ordering::Less    => recursive_binary_search(&list[..guess], target),
        Ordering::Greater => recursive_binary_search(&list[guess..], target),
        Ordering::Equal   => true,
    }
}
使用std::cmp::排序;
fn递归二进制搜索(列表:&[T],目标:T)->bool{
如果列表为空(){
返回false;
}
让guess=list.len()/2;
匹配target.cmp(&list[猜测]){
排序::Less=>递归二进制搜索(&list[…guess],target),
排序::更大=>递归\u二进制\u搜索(&list[guess+1..],target),
排序::Equal=>true,
}
}
fn main(){
断言!(!递归二进制搜索(&[1,2,3,4,5],0));
断言!(递归二进制搜索(&[1,2,3,4,5],1));
断言!(递归二进制搜索(&[1,2,3,4,5],2));
断言!(递归二进制搜索(&[1,2,3,4,5],3));
断言!(递归二进制搜索(&[1,2,3,4,5],4));
断言!(递归二进制搜索(&[1,2,3,4,5],5));
断言!(!递归二进制搜索(&[1,2,3,4,5],6));
}

如果你不是出于学习的目的来实现这一点,请使用内置的。

情商特征不是没有必要吗?Ord包含PartialOrd+Eq。是的,当然这只是为了学习。@leshow yep;我不假思索地复制了它;在上一个版本中删除了它,它还修复了无限递归错误。感谢match的提示,这是一个很好的rust-y编写方法。
use std::cmp::Ordering;

fn recursive_binary_search<T: Ord>(list: &[T], target: T) -> bool {
    if list.is_empty() {
        return false;
    }

    let guess = list.len() / 2;

    match target.cmp(&list[guess]) {
        Ordering::Less    => recursive_binary_search(&list[..guess], target),
        Ordering::Greater => recursive_binary_search(&list[guess+1..], target),
        Ordering::Equal   => true,
    }
}

fn main() {
    assert!(!recursive_binary_search(&[1,2,3,4,5], 0));
    assert!(recursive_binary_search(&[1,2,3,4,5], 1));
    assert!(recursive_binary_search(&[1,2,3,4,5], 2));
    assert!(recursive_binary_search(&[1,2,3,4,5], 3));
    assert!(recursive_binary_search(&[1,2,3,4,5], 4));
    assert!(recursive_binary_search(&[1,2,3,4,5], 5));
    assert!(!recursive_binary_search(&[1,2,3,4,5], 6));
}