树递归 - 如何避免“函数结束时缺少返回”?

对于昆虫组合学的实验室问题,以下是我使用树递归的解决方案:


func Paths(m int, n int) int {

    length := m

    width := n


    var f func(int, int) int


    f = func(h int, v int) int {

        if h == width && v == length {

            return 1

        } else if h < width && v < length {

            return f(h, v+1) + f(h+1, v)

        } else if v < length {

            return f(h, v+1)

        } else if h < width {

            return f(h+1, v)

        } /*else { // this condition doesn't occur

            return 0

        }*/

    } // Line 19


    return f(1, 1)

}

else上述解决方案不需要块(无效),但编译器missing return error在第 19 行给出


如何避免missing return error上述代码?


RISEBY
浏览 143回答 2
2回答

互换的青春

Go 不知道这一点// this condition doesn't occur,并且在分析您的代码时,它会看到如果没有if满足语句的条件,则它缺少返回值。“解决”此问题的一种方法是执行类似panic("does not occur"). 不过,我不喜欢这样,因为多年来我遇到了太多的日志条目说“不会发生”......或者,您可以使用 Go 中可能更自然的方法:if cond1 {&nbsp; return v1}if cond2 {&nbsp; return v2}//... other cases ...&nbsp;return v3或者甚至是一个 switch 语句:switch {case cond1:&nbsp; return v1case cond2:&nbsp; return v2//... other cases ...&nbsp;default:&nbsp; return v3}&nbsp;您使用的“else if”是不必要的,因为每种情况都会导致函数立即返回。检查 Effective Go 以了解此模式。它也在标准库中被广泛使用(即,避免不必要的 else's)。另外,由于您说绝对不可能所有条件都是错误的,因此无需测试最后一个:这是“其他”情况。

皈依舞

您明确指出函数 f 返回一个 int,问题是此函数中存在条件不满足您的任何 if...elseif 条件的情况:package mainimport "fmt"func main() {&nbsp; &nbsp; fmt.Println(Paths(0, 0))&nbsp; &nbsp; fmt.Println(Paths(1, 0))&nbsp; &nbsp; fmt.Println(Paths(0, 1))}func Paths(m int, n int) int {&nbsp; &nbsp; length := m&nbsp; &nbsp; width := n&nbsp; &nbsp; var f func(int, int) int&nbsp; &nbsp; f = func(h int, v int) int {&nbsp; &nbsp; &nbsp; &nbsp; if h == length && v == width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 1&nbsp; &nbsp; &nbsp; &nbsp; } else if h < width && v < width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h, v+1) + f(h+1, v)&nbsp; &nbsp; &nbsp; &nbsp; } else if v < length {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h, v+1)&nbsp; &nbsp; &nbsp; &nbsp; } else if h < width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h+1, v)&nbsp; &nbsp; &nbsp; &nbsp; } else { // this condition does occur&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } // Line 19&nbsp; &nbsp; return f(1, 1)}所以这些场景是函数允许的。您可能会在输入此函数之前验证这些值,但问题是此函数不执行任何操作,并且传递这些值是有效的。如果你有信心 0,0; 0,1; 并且 1,0 不会是输入值,您可以else if h < width {通过 else 来避免最后一个;但是这会改变函数的逻辑。同样,鉴于函数 Paths 已导出,您可能应该对传入的值进行验证,如果您需要确保 0,0; 0,1; 和 1;0 选项是不允许的。如果它符合您的目的,您可以在函数末尾有一个 return ,用于返回 0 或 -1 以指示该值不正确。就个人而言,如果这些值在函数中不可接受,最好验证输入并返回错误,或者如果必须,请恐慌。func Paths(m int, n int) int {&nbsp; &nbsp; length := m&nbsp; &nbsp; width := n&nbsp; &nbsp; var f func(int, int) int&nbsp; &nbsp; f = func(h int, v int) int {&nbsp; &nbsp; &nbsp; &nbsp; if h == length && v == width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 1&nbsp; &nbsp; &nbsp; &nbsp; } else if h < width && v < width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h, v+1) + f(h+1, v)&nbsp; &nbsp; &nbsp; &nbsp; } else if v < length {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h, v+1)&nbsp; &nbsp; &nbsp; &nbsp; } else if h < width {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return f(h+1, v)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return 0&nbsp; &nbsp; }&nbsp; &nbsp; return f(1, 1)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go