golang 笔试题 按序打印

题目

var Foo struct {
step int32
First func()
Second func()
Third func()
first func()
second func()
third func()
}
Foo.first = func() { fmt.Println("first") }
Foo.second = func() { fmt.Println("second") }
Foo.third = func() { fmt.Println("third") }

一个将会调用 First() 方法, 一个将会调用 Second() 方法,还有一个将会调用 Third() 方法,
请实现First()/Second()/ Third(),以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。

代码

package main

import (
"fmt"
"strings"
"sync"
"sync/atomic"
)
func main() {
   var Foo struct {
      step   int32
      First  func()
      Second func()
      Third  func()
      first  func()
      second func()
      third  func()
   }
   Foo.first = func() { fmt.Println("first") }
   Foo.second = func() { fmt.Println("second") }
   Foo.third = func() { fmt.Println("third") }

   wg := sync.WaitGroup{}

  
   Foo.First = func() {
      defer wg.Done()
      for atomic.LoadInt32(&Foo.step) != 0 {
         continue
      }
      Foo.first()
      atomic.StoreInt32(&Foo.step,1)
   }
   Foo.Second = func() {
      defer wg.Done()
      for atomic.LoadInt32(&Foo.step) != 1 {
         continue
      }
      Foo.second()
      atomic.StoreInt32(&Foo.step,2)

   }
   Foo.Third = func() {
      defer wg.Done()
      for atomic.LoadInt32(&Foo.step) != 2 {
         continue
      }
      Foo.third()
      atomic.StoreInt32(&Foo.step,0)
   }
   wg.Add(3)
   go Foo.First()
   go Foo.Second()
   go Foo.Third()
   wg.Wait()

   wg.Add(3)
   go Foo.Second()
   go Foo.First()
   go Foo.Third()
   wg.Wait()

   wg.Add(3)
   go Foo.Third()
   go Foo.Second()
   go Foo.First()
   wg.Wait()
}

运行结果