LoginSignup
5
4

More than 5 years have passed since last update.

Go言語: channelを使ってActorっぽいことをしたい

Last updated at Posted at 2015-05-02

Go言語で、Actorっぽいことができないか試してみました。Go Playgroundで動作するサンプルを試せます。

package main

import (
    "log"
    "time"
)

func main() {
    log.Println("started")
    actor := NewActor()
    go actor.React()

    // send Increment per second
    go func() {
        for i := 0; i <= 10; i++ {
            actor.Increment <- &Increment{}
            time.Sleep(1 * time.Second)
        }
    }()

    // send Decrement per two seconds
    go func() {
        for i := 0; i <= 10; i++ {
            actor.Decrement <- &Decrement{}
            time.Sleep(2 * time.Second)
        }
    }()

    // send Stop in seven seconds
    go func() {
        time.Sleep(7 * time.Second)
        actor.Stop <- &Stop{}
    }()

    // send Letter per two seconds
    go func() {
        messages := []string{"hi!", "yo!"}
        for _, msg := range messages {
            time.Sleep(2 * time.Second)
            actor.Letter <- &Letter{msg}
        }
    }()

    // wait for all messages are sent.
    time.Sleep(10 * time.Second)

    log.Println("finished")
}

type Increment struct {
}

type Decrement struct {
}

type Stop struct {
}

type Letter struct {
    Body string
}

type Actor struct {
    number    int
    Increment chan *Increment
    Decrement chan *Decrement
    Letter    chan *Letter
    Stop      chan *Stop
}

func NewActor() *Actor {
    return &Actor{
        number:    0,
        Increment: make(chan *Increment),
        Decrement: make(chan *Decrement),
        Letter:    make(chan *Letter),
        Stop:      make(chan *Stop),
    }
}

func (a *Actor) React() {
    for {
        select {
        case <-a.Increment:
            a.number += 1
            log.Printf("incremented: %d", a.number)
        case <-a.Decrement:
            a.number -= 1
            log.Printf("decremented: %d", a.number)
        case letter := <-a.Letter:
            log.Printf("letter recieved: %s", letter.Body)
        case <-a.Stop:
            log.Println("stopping")
            return
        }
    }
}

実行結果

2009/11/10 23:00:00 started
2009/11/10 23:00:00 incremented: 1
2009/11/10 23:00:00 decremented: 0
2009/11/10 23:00:01 incremented: 1
2009/11/10 23:00:02 decremented: 0
2009/11/10 23:00:02 letter recieved: hi!
2009/11/10 23:00:02 incremented: 1
2009/11/10 23:00:03 incremented: 2
2009/11/10 23:00:04 decremented: 1
2009/11/10 23:00:04 incremented: 2
2009/11/10 23:00:04 letter recieved: yo!
2009/11/10 23:00:05 incremented: 3
2009/11/10 23:00:06 decremented: 2
2009/11/10 23:00:06 incremented: 3
2009/11/10 23:00:07 stopping
2009/11/10 23:00:10 finished
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4