Golang中如何在循环中调用函数

Golang中如何在循环中调用函数

我是Go语言的新手。最近在编写代码时遇到了一个奇怪的问题,代码如下:

```go
// scanFunc 是一个闭包
	for pos := scanFunc(list[beg:end]) ; middle != pos ; pos = scanFunc(list[beg:end]) {
            fmt.Printf("Scan %v, %v, result %v\n",beg,end,pos)
  if middle < pos {
  	end = pos + 1
  }else{
  	beg = pos
  }
  middle = ( beg + end  ) / 2
}

这段代码在运行前需要极长的编译时间,并且不会打印调试信息。

我猜想可能是因为Go语言在编译时展开了函数调用,导致beg和end的值被固定而不是实时计算,但我不太确定这一点。

有人对此有什么看法吗?


更多关于Golang中如何在循环中调用函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

从未听说过类似情况。能否提供一个完整示例,以及你采取的编译步骤?如果目前不是这样操作的话,建议使用 go install

// 代码示例应放置于此

更多关于Golang中如何在循环中调用函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,循环中调用函数是完全可行的,但根据你提供的代码,问题可能出现在循环条件或闭包的使用方式上。Go编译器不会在编译时展开函数调用或固定变量值,除非涉及常量表达式。你的代码中begend在循环体内被修改,因此它们应该是动态计算的。

问题可能在于:

  1. 循环条件逻辑错误:如果scanFunc返回的值与middle的比较导致无限循环,循环可能永远不会进入或退出,从而不打印调试信息。
  2. 闭包行为异常scanFunc是一个闭包,如果它依赖于外部变量且这些变量在循环中被修改,闭包可能捕获了意外的状态,导致返回结果不符合预期。

让我重构你的代码,添加更详细的调试信息,并确保闭包正确使用。假设scanFunc是一个接受切片并返回整数的函数,这里是一个示例:

// 假设 scanFunc 是一个闭包,定义在外部,例如:
// scanFunc := func(slice []int) int { ... 返回一个位置 }

// 初始化变量
beg := 0
end := len(list)
middle := (beg + end) / 2

// 使用循环调用 scanFunc
for {
    pos := scanFunc(list[beg:end])  // 调用闭包函数,传递当前切片
    fmt.Printf("Scan: beg=%d, end=%d, middle=%d, pos=%d\n", beg, end, middle, pos)
    
    // 检查是否满足退出条件
    if middle == pos {
        break  // 退出循环
    }
    
    // 根据 pos 和 middle 的关系更新 beg 或 end
    if middle < pos {
        end = pos + 1
    } else {
        beg = pos
    }
    
    // 重新计算 middle
    middle = (beg + end) / 2
    
    // 添加安全措施,防止无限循环(例如,限制迭代次数)
    // 例如:if someMaxIterations--; someMaxIterations <= 0 { break }
}

在这个示例中:

  • 我使用了无限循环for {},并在条件满足时使用break退出,这比在循环条件中直接调用函数更清晰。
  • 添加了详细的fmt.Printf语句来打印begendmiddlepos的值,帮助调试。
  • 确保scanFunc在每次迭代中都被调用,并传递更新后的list[beg:end]切片。
  • 建议添加迭代次数限制作为安全措施,避免无限循环。

如果你的原始代码编译时间极长,可能是由于其他因素(如代码复杂度、依赖问题或IDE设置),而不是Go编译器展开函数调用。Go的编译通常是快速的,除非涉及大量代码或复杂优化。运行这个修改后的版本,检查输出以识别问题所在。如果问题 persist,请检查scanFunc的实现是否正确处理了切片边界。

回到顶部