2015-04-01 54 views
0

我正在研究Project Euler問題以適應Go。問題不在於歐拉項目,而是在這個問題中有項目歐拉特定的代碼,可能會帶來一個問題的挑戰。 「尾翼警報」或其他,但現在你知道。這是我的文件結構:從外部文件導入時功能不正常,但在同一文件中正常工作?

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

對於問題23,我加入了新的功能SumOfDivisors到util.go(用各種方法文件由多個問題中使用):

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:

package main 

import (
    "fmt" 
    "util" 
) 

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

我有我的GOPATH設置爲/Project Euler/Go和它建立,當我打電話0運行看似細。 「看起來很好」意味着沒有錯誤,警告,除我的代碼外沒有任何輸出。

什麼是打印到屏幕是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。什麼可能導致這種行爲?該功能在本地正常工作,但在移動到已導入的外部文件時無法正常工作,爲什麼不能在該外部文件上打印任何內容?所有這一切,而建設很好。

+0

我無法重複在Windows上運行Go 1.2的這個問題。也許這是一個錯誤? – 2015-04-01 22:51:49

+0

我發現我需要做些什麼來解決這個問題,但我仍然在爲解釋是什麼造成的。我不知道是什麼導致'util.a'被緩存。 – 2015-04-01 22:55:48

回答

1

經過多一點的捧場,我發現裏面存在一個/Project Euler/pkg文件夾,裏面有util.a。顯然,我的代碼版本是建立的,它的中間文件被緩存了。

刪除pkg文件夾後,所有東西都落到了位置。不匹配的函數名稱變成了編譯器錯誤,然後(在糾正函數名稱後),我的util.go fmt.Println調用開始打印,我的答案出現爲16。最終,這不是一個代碼解決方案,而是一個緩存問題。

+0

這是使用'go install'而不是'go build'或'go run'的另一個原因 – JimB 2015-04-01 23:03:13

+0

當我開始使用Go並且告訴你什麼的時候,這發生在我身上..我失去了大量的時間來搞清楚問題是什麼。很高興你把事情解決了。 – 2015-04-01 23:06:19

+0

我仍然開放以瞭解創建pkg文件夾及其內容的內容。至少我想出了我的「代碼斷開」問題。 – 2015-04-01 23:08:14

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瞭解更多信息。

+0

「跑步」適用於完全獨立的腳本式程序,但就是這樣。 – twotwotwo 2015-04-02 05:38:52

+0

@twotwotwo,是的。如果他只是構建一個包,那麼他可以使用'build'來代替。並跑步跑步。 – 2015-04-03 20:46:38