为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
RISEBY 2022-06-06 18:02:55
对于昆虫组合学的实验室问题,以下是我使用树递归的解决方案: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上述代码?
查看完整描述

2 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

Go 不知道这一点// this condition doesn't occur,并且在分析您的代码时,它会看到如果没有if满足语句的条件,则它缺少返回值。


“解决”此问题的一种方法是执行类似panic("does not occur"). 不过,我不喜欢这样,因为多年来我遇到了太多的日志条目说“不会发生”......


或者,您可以使用 Go 中可能更自然的方法:


if cond1 {

  return v1

}

if cond2 {

  return v2

}

//... other cases ... 

return v3

或者甚至是一个 switch 语句:


switch {

case cond1:

  return v1

case cond2:

  return v2

//... other cases ... 

default:

  return v3

您使用的“else if”是不必要的,因为每种情况都会导致函数立即返回。检查 Effective Go 以了解此模式。它也在标准库中被广泛使用(即,避免不必要的 else's)。


另外,由于您说绝对不可能所有条件都是错误的,因此无需测试最后一个:这是“其他”情况。


查看完整回答
反对 回复 2022-06-06
?
皈依舞

TA贡献1851条经验 获得超3个赞

您明确指出函数 f 返回一个 int,问题是此函数中存在条件不满足您的任何 if...elseif 条件的情况:


package main


import "fmt"


func main() {

    fmt.Println(Paths(0, 0))

    fmt.Println(Paths(1, 0))

    fmt.Println(Paths(0, 1))

}


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 == length && v == width {

            return 1

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

            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 does occur

            return 0

        }

    } // Line 19


    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 {

    length := m

    width := n


    var f func(int, int) int


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

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

            return 1

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

            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)

        }


        return 0

    }


    return f(1, 1)

}


查看完整回答
反对 回复 2022-06-06
  • 2 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信