从外部文件导入时功能不正常但在同一文件中时功能正常?

时间:2015-04-01 22:35:10

标签: go

我正在研究Project Euler的问题,以便习惯Go。问题不在于项目欧拉,但在这个问题中有项目欧拉特定代码可能会带来问题的挑战。 "剧透警报"或者其他什么,但现在你知道了。这是我的文件结构:

+ Project Euler
+-+ Go       <= GOPATH set here
  +-+ src
    +-+ util
    | +- util.go
    |
    +- 001.go
    +- 002.go
    ...
    +- 023.go

对于问题23,我在util.go中添加了一个新函数SumOfDivisors(一个文件包含多个问题使用的各种方法):

func GetPrimeFactors(val int) map[int]int {
    primes := map[int]int{}
    init := val
    num := 2
    for val > 1 {
        if (val % num) == 0 {
            if num == init {
                return nil
            }
            _, e := primes[num]
            if e {
                primes[num]++
            } else {
                primes[num] = 1
            }
            val /= num
        } else {
            num++
        }
    }
    return primes
}

func SumOfDivisors(val int) int {
    primes := GetPrimeFactors(val)
    if primes == nil {
        if val == 0 {
            return 0
        } else {
            return 1
        }
    }
    total := 1
    for k, v := range primes {
        if v > 1 {
            n := int((math.Pow(float64(k), float64(v+1)) - 1) / float64(k-1))
            total *= n
        } else {
            n := k + 1
            total *= n
        }
    }
    return total - val
}

为了测试这个方法,我在023.go中写了这个基本的Go:

package main

import (
    "fmt"
    "util"
)

func main() {
    fmt.Println(util.SumOfDivisors(12))
}

我将GOPATH设置为/Project Euler/Go,当我拨打go run 023.go时,它的构建和运行看似很好。 &#34;看似很好&#34;意思是没有错误,警告,除了我的代码之外没有输出。

屏幕打印的内容为1时应为16。我不认为这是一个逻辑问题,因为当我将函数从我的util.go复制到023.go(并修复对GetPrimeFactors的调用是util.GetPrimeFactors)时,该函数运行得很好并打印16就像它应该的那样。我已尝试将fmt.Println("TEST")添加到util.SumOfDivisors,但它不会打印出这些陈述,我也不会收到错误或其他任何内容。如果我将util.go中的函数名称更改为其他任何内容,即使主函数023.go没有更改,它仍会构建并运行输出1。它真的很奇怪。

我的util.go文件中的其他函数似乎被称为正常。

我正在运行Go 1.4.2。可能导致这种行为的原因是什么?该功能在本地正常工作,但在移动到导入的外部文件时不能正常工作,为什么外部文件不能打印任何屏幕?这一切都很好。

2 个答案:

答案 0 :(得分:3)

使用go build -a 023.go

这将重建023.go所具有的所有依赖项,并将避免使用旧的编译版本的程序包。这是一种强大的套装,可以缩短构建时间,但也会导致这些类型的问题。

正如我在评论中提到的,你一直在构建023.go,但你可能没有运行go build util.go来更新023.go所依赖的util包。

-a选项将重建所有依赖项,您甚至可以添加-v以查看它正在构建的内容以及何时构建。

go build -a -v 023.go

OR

go run -a -v 023.go

运行,构建,清理和测试具有类似的标志。运行go help build了解详情。

答案 1 :(得分:1)

经过多一点玩耍后,我发现其中存在一个/Project Euler/pkg文件夹,其中包含util.a。显然我的代码版本已经构建,它的中间文件被缓存了。

删除pkg文件夹后,一切都落到了位置。不匹配的函数名称成为编译器错误,然后(在更正函数名称后)我的util.go fmt.Println调用开始打印,我的答案显示为16。最后这不是一个代码解决方案,这是一个缓存问题。