我試圖實現一個非常簡單的測試函數來驗證來自我的歐拉問題解決方案的結果。Go - 編譯一組函數時出錯
在下面的代碼中,我創建了一張切片圖,其中索引爲0,我調用返回一個整數的函數,並在索引1上調用我期望從該函數得到的結果。
package euler
import "testing"
func TestEulers(t *testing.T) {
tests := map[string][]int{
"Euler1": {Euler1(), 233168},
"Euler2": {Euler2(), 4613732},
"Euler3": {Euler3(), 6857},
"Euler4": {Euler4(), 906609},
"Euler5": {Euler5(), 232792560},
"Euler6": {Euler6(), 25164150},
}
for key, value := range tests {
if value[0] != value[1] {
t.Errorf("%s\nExpected: %d\nGot:%d",
key, value[0], value[1])
}
}
}
對於地圖,各功能工作正常並返回結果我想到如果我運行一個接一個,或者如果我的評論,讓我們說,這些鍵/值的半部分。
例如,如果我用上面的函數調用上面的函數註釋,測試會通過。
tests := map[string][]int{
"Euler1": {Euler1(), 233168},
// "Euler2": {Euler2(), 4613732},
"Euler3": {Euler3(), 6857},
"Euler4": {Euler4(), 906609},
// "Euler5": {Euler5(), 232792560},
// "Euler6": {Euler6(), 25164150},
}
但是,如果我安排在下一個方式的意見,例如,測試不會。
tests := map[string][]int{
//"Euler1": {Euler1(), 233168},
"Euler2": {Euler2(), 4613732},
"Euler3": {Euler3(), 6857},
"Euler4": {Euler4(), 906609},
//"Euler5": {Euler5(), 232792560},
// "Euler6": {Euler6(), 25164150},
}
測試會給我一個錯誤:
WARNING: DATA RACE
Write by goroutine 6:
runtime.closechan()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/chan.go:295 +0x0
github.com/alesr/project-euler.Euler2()
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler.go:40 +0xd7
github.com/alesr/project-euler.TestEulers()
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler_test.go:9 +0x46
testing.tRunner()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:456 +0xdc
Previous read by goroutine 7:
runtime.chansend()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/chan.go:107 +0x0
github.com/alesr/numbers.FibonacciGen.func1()
/Users/Alessandro/GO/src/github.com/alesr/numbers/numbers.go:103 +0x59
Goroutine 6 (running) created at:
testing.RunTests()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:561 +0xaa3
testing.(*M).Run()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:494 +0xe4
main.main()
github.com/alesr/project-euler/_test/_testmain.go:54 +0x20f
Goroutine 7 (running) created at:
github.com/alesr/numbers.FibonacciGen()
/Users/Alessandro/GO/src/github.com/alesr/numbers/numbers.go:105 +0x60
github.com/alesr/project-euler.Euler2()
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler.go:27 +0x32
github.com/alesr/project-euler.TestEulers()
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler_test.go:9 +0x46
testing.tRunner()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:456 +0xdc
==================
panic: send on closed channel
goroutine 36 [running]:
github.com/alesr/numbers.FibonacciGen.func1(0xc8200a01e0)
/Users/Alessandro/GO/src/github.com/alesr/numbers/numbers.go:103 +0x5a
created by github.com/alesr/numbers.FibonacciGen
/Users/Alessandro/GO/src/github.com/alesr/numbers/numbers.go:105 +0x61
goroutine 1 [chan receive]:
testing.RunTests(0x24d038, 0x2f7340, 0x1, 0x1, 0xf78401)
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:562 +0xafa
testing.(*M).Run(0xc82004df00, 0x1ff0e8)
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:494 +0xe5
main.main()
github.com/alesr/project-euler/_test/_testmain.go:54 +0x210
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/asm_amd64.s:1696 +0x1
goroutine 35 [runnable]:
github.com/alesr/strings.Flip(0xc8200727a0, 0x6, 0x0, 0x0)
/Users/Alessandro/GO/src/github.com/alesr/strings/strings.go:33 +0x17e
github.com/alesr/project-euler.Euler4(0x1ac9)
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler.go:73 +0x95
github.com/alesr/project-euler.TestEulers(0xc8200b6000)
/Users/Alessandro/GO/src/github.com/alesr/project-euler/euler_test.go:11 +0x63
testing.tRunner(0xc8200b6000, 0x2f7340)
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:456 +0xdd
created by testing.RunTests
/private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:561 +0xaa4
exit status 2
FAIL github.com/alesr/project-euler 0.022s
但儘管如此,我檢查每一個功能,如預期,他們只是工作。 如果需要,您可以訪問Euler source code或包numbers和strings。
在Euler2函數我有一個延遲語句來關閉從FibonacciGen接收的通道。
而在FibonacciGen上,我確實有另一個延遲語句來關閉同一個通道。
看來這是我的第一個錯誤。我應該只有一個而不是兩個聲明來關閉這個頻道,因爲他們試圖關閉同一個事物。那是對的嗎?
其次(在這裏我甚至有點不確定),延遲語句將阻止函數在主要goroutine返回之前被調用,對吧?獨立的,如果我打包的主要或不是?
另外,由於數據正在流過從FibonacciGen到主函數的通道。在我看來,如果我關閉了FibonacciGen的頻道,我不需要通知主函數。但是,如果我關閉主要功能的頻道,我必須通知斐波納契Gen停止嘗試發送到此頻道。
在'Euler2'功能,您封閉的通道通過'FibonacciGen'產生,但發電機不知道這件事,仍然試圖發送到恐慌當你看到封閉的通道。您需要通知發電機停止寫入該頻道。 –
但是,如果我只運行歐拉2功能,我會得到沒有錯誤。爲什麼? –
goroutine的調度很重要,通過'time.Sleep'或者'runtime.Gosched'強制重新調度,以便其他goroutine可以繼續。然後,你應該看到同樣的錯誤。 –