1

http://play.golang.org/p/r92-KtQEGl

我正在尝试执行此代码。它会引发死锁错误。

我错过了什么?

package main

import "tour/tree"
import "fmt"

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int){
    var temp chan int
    ch <- t.Value
    if t.Left!=nil{go Walk(t.Left,temp)}
    if t.Right!=nil{go Walk(t.Right,temp)}
    for i := range temp{
        ch <- i
    }
    close(ch)
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool
4

2 回答 2

3

所以我通过向 Walk 函数发送一个标志来做到这一点。这样它就知道何时可以关闭通道。我也认为以正确的顺序左节点、值、右节点遍历树很重要。

package main

import (
  "fmt"
  "tour/tree"
)

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, c chan int, d bool) {
  if t.Left != nil {
    Walk(t.Left, c, false)
  } 
  c <- t.Value

  if t.Right != nil {
    Walk(t.Right, c, false)
  }
  if d {
    close(c)
  }
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
  ch1 := make(chan int)
  ch2 := make(chan int)
  go Walk(t1, ch1, true)
  go Walk(t2, ch2, true)
  for {
    v1, ok1 := <-ch1
    v2, ok2 := <-ch2

    if v1 != v2 {
      return false
    }
    if ok1 != ok2 {
      return false
    } 
    if !ok1 && !ok2 {
      return true
    }
  }
  return false
}
func main() {
  ch := make(chan int)
  go Walk(tree.New(1), ch, true)

  for i := range ch {
    fmt.Println(i)
  } 

  test1 := Same(tree.New(1), tree.New(1))
  test2 := Same(tree.New(1), tree.New(2))

  fmt.Println(test1, test2)
}
于 2012-09-30T17:57:32.007 回答
1

您至少需要初始化您的频道(如果频道为零,则范围将永远阻塞)

  var temp chan int = make(chan int)
  var ch chan int = make(chan int)

http://play.golang.org/p/Gh8MZlyd3B(仍然死锁但至少显示结果)

这个版本,使用两个临时通道,不会死锁:http ://play.golang.org/p/KsnmKTgZ83

package main

import "tour/tree"
import "fmt"

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
    var temp1 chan int = make(chan int)
    var temp2 chan int = make(chan int)
    ch <- t.Value
    if t.Left != nil {
        go Walk(t.Left, temp1)
    }
    if t.Right != nil {
        go Walk(t.Right, temp2)
    }
    if t.Left != nil {
        for i := range temp1 {
            ch <- i
        }
    }
    if t.Right != nil {
        for i := range temp2 {
            ch <- i
        }
    }
    close(ch)
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool

func main() {
    var ch chan int = make(chan int)
    go Walk(tree.New(1), ch)
    for i := range ch {
        fmt.Println(i)
    }
}
于 2012-09-28T07:55:25.697 回答