dongque4778 2015-12-14 22:32
浏览 74


I'm trying to implement a very simple test function to verify results coming from my solutions for Euler problems.

In the following code I've created a map of slices where on the index 0, I call the function which return a integer and on the index 1, the result I expect from that function.

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] {
Expected: %d
                key, value[0], value[1])

For that map, every function works fine and return the result I expect if I run one by one or if I comment, let's say, half part of those keys/values.

For example, if I call the the function above with these lines commented the test will PASS.

tests := map[string][]int{
    "Euler1": {Euler1(), 233168},
    // "Euler2": {Euler2(), 4613732},
    "Euler3": {Euler3(), 6857},
    "Euler4": {Euler4(), 906609},
    // "Euler5": {Euler5(), 232792560},
    // "Euler6": {Euler6(), 25164150},

But if I arrange the comments on that next way, for example, the test wouldn't.

tests := map[string][]int{
        //"Euler1": {Euler1(), 233168},
        "Euler2": {Euler2(), 4613732},
        "Euler3": {Euler3(), 6857},
        "Euler4": {Euler4(), 906609},
        //"Euler5": {Euler5(), 232792560},
        // "Euler6": {Euler6(), 25164150},

The test will give me an error:

Write by goroutine 6:
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/chan.go:295 +0x0
      /Users/Alessandro/GO/src/ +0xd7
      /Users/Alessandro/GO/src/ +0x46
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:456 +0xdc

Previous read by goroutine 7:
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/chan.go:107 +0x0
      /Users/Alessandro/GO/src/ +0x59

Goroutine 6 (running) created at:
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:561 +0xaa3
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main() +0x20f

Goroutine 7 (running) created at:
      /Users/Alessandro/GO/src/ +0x60
      /Users/Alessandro/GO/src/ +0x32
      /Users/Alessandro/GO/src/ +0x46
      /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/testing/testing.go:456 +0xdc
panic: send on closed channel

goroutine 36 [running]:
    /Users/Alessandro/GO/src/ +0x5a
created by
    /Users/Alessandro/GO/src/ +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() +0x210

goroutine 17 [syscall, locked to thread]:
    /private/var/folders/q8/bf_4b1ts2zj0l7b0p1dv36lr0000gp/T/workdir/go/src/runtime/asm_amd64.s:1696 +0x1

goroutine 35 [runnable]:, 0x6, 0x0, 0x0)
    /Users/Alessandro/GO/src/ +0x17e
    /Users/Alessandro/GO/src/ +0x95
    /Users/Alessandro/GO/src/ +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  0.022s

But still, I checked every single function and they work just as expected. You can access the Euler source code or the packages numbers and strings if you want.

At Euler2 function I have a defer statement to close the channel which is receiving from FibonacciGen.

And on FibonacciGen I do have another defer statement to close the same channel.

It seems that's the my first error. I should have just one and not two statements to close the channel, since they are trying to close the same thing. Is that correct?

Second (and here I'm even a little more unsure), the defer statement will prevent the function to be called until the main goroutine returns, right? Independently if I call it on the package main or not?

Plus, since the data is flowing through the channel from FibonacciGen to the main function. It seems for me, that if I close the channel at FibonacciGen I don't need to notify the main function. But If I close the channel on the main function I do have to notify FibonacciGen to stop trying to send to this channel.

  • 写回答

2条回答 默认 最新

  • 普通网友 2015-12-19 23:18

    Thank you all. With your help I could understand that I was closing the channel in the wrong way.

    Now works correctly.

    func Euler2() int {
        c := make(chan int)
        done := make(chan bool)
        go numbers.FibonacciGen(c, done)
        sum := 0
        var f int
        for {
            f = <-c
            if f < 4000000 {
                if f%2 == 0 {
                    sum += f
            } else {
                return sum
    func FibonacciGen(c chan int, done chan bool) {
        for {
            select {
            case <-done:
                for i, j := 0, 1; ; i, j = i+j, i {
                    c <- i
    本回答被题主选为最佳回答 , 对您是否有帮助呢?



  • ¥50 内网的网页打开的Excel下载到本地
  • ¥15 该网站用的是什么程序模版
  • ¥15 verilog modelsim仿真
  • ¥15 Power BI 里面 帕累托图突出显示前20
  • ¥50 用预估矫正法,分数阶微分方程组传染病的最优控制代码怎么写
  • ¥15 画个数据流程图,手画也行
  • ¥60 AS自带模拟器AVD Root 和 Xposed安装
  • ¥30 哪位搞Android的编程师可以帮我远程一下,悬赏30元
  • ¥15 solidity部署上合约,可以mint,也继承接口了,在区块链也不显示代币名字
  • ¥15 讨论 博士论文交互项怎么讨论?