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

少なくともチャンネルを初期化する必要があります (チャンネルが nil の場合、範囲は永久にブロックされます)

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

http://play.golang.org/p/Gh8MZlyd3Bを参照してください(まだデッドロックですが、少なくとも結果は表示されます)

2 つの一時チャネルを使用するこのバージョンはデッドロックしません: 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 に答える