dsk61780 2014-10-11 15:01
浏览 44
已采纳

如何将示例代码从Go转换为Erlang

I thought I could kill two birds with one stone and teach myself a little Go and Erlang by converting the following example code (taken from http://blog.smartbear.com/programming/an-introduction-to-the-go-language-boldly-going-where-no-man-has-ever-gone-before/) from Go to Erlang:

package main

import (
    "fmt"
    "time"
)

type Ball struct{ hits int }

func main() {
    table := make(chan *Ball)
    go player("ping", table)
    go player("pong", table)
    table <- new(Ball) // game on; toss the ball
    time.Sleep(1 * time.Second)
    <-table // game over; grab the ball
}

func player(name string, table chan *Ball) {
    for {
        ball := <-table
        ball.hits++
        fmt.Println(name, ball.hits)
        time.Sleep(100 * time.Millisecond)
        table <- ball
    }
}

However I failed. The code basically creates a shared counter (the ball) and sends it back and forth between the two goroutines (the players). So far so good. But how do I do something similar in Erlang? My problems were:

  • How to create a counter in Erlang? Erlang doesn't seem to allow to change the value of a variable once it is set.
  • How to share such a counter between two erlang processes?
  • 写回答

1条回答 默认 最新

  • dpoppu4300 2014-10-11 17:02
    关注

    A variable is not mutable in erlang, that means that during the evaluation of one function, the variable is either unbound, either set to a value that cannot change. But you can recall the same function with a new value build from the former one, recursively. The value is stored in a variable generally called the state, and it is modified when a message is received. This is the basic behaviour of a server.

    In your example you don't really need a variable to contain the counter since this value will be exchange between the 2 players. I can be contained in the message exchanged between them for example in a tuple {count,V}.

    The only way to communicate between 2 processes is message passing. The simplest syntax is Pid ! Message, where Pid is the process ID if the receiver, and Message , well the message :o) (Pid can be replaced by a name if the process is registered).

    with this you can write:

    -module(pingpong).
    -export([start/0,player/1,stop/1]).
    
    player(Name) ->
        receive
            {count,From,Val} -> 
                io:format("~p received the ball for the ~p th exchange~n",[Name,Val]),
                ok = timer:sleep(500),
                From ! {count,self(),Val+1},
                player(Name);
            {start,To} ->
                io:format("~p start the exchange~n",[Name]),
                To ! {count,self(),1},
                player(Name);
             stop -> gameover
         end.
    
    start() ->
        Ping = spawn(?MODULE,player,[ping]),
        Pong = spawn(?MODULE,player,[pong]),
        Ping ! {start,Pong},
        {Ping,Pong}.
    
    stop(P1) -> P1 ! stop. 
    

    in the shell:

    1> c(pingpong).
    {ok,pingpong}
    2> {P1,P2} = pingpong:start().
    ping start the exchange
    pong received the ball for the 1 th exchange
    {<0.39.0>,<0.40.0>}
    ping received the ball for the 2 th exchange
    pong received the ball for the 3 th exchange
    ping received the ball for the 4 th exchange
    pong received the ball for the 5 th exchange
    ping received the ball for the 6 th exchange
    pong received the ball for the 7 th exchange
    ping received the ball for the 8 th exchange
    pong received the ball for the 9 th exchange
    ping received the ball for the 10 th exchange
    pong received the ball for the 11 th exchange
    ping received the ball for the 12 th exchange
    pong received the ball for the 13 th exchange
    ping received the ball for the 14 th exchange
    pong received the ball for the 15 th exchange
    ping received the ball for the 16 th exchange
    pong received the ball for the 17 th exchange
    ping received the ball for the 18 th exchange
    pong received the ball for the 19 th exchange
    ping received the ball for the 20 th exchange
    pong received the ball for the 21 th exchange
    ping received the ball for the 22 th exchange
    pong received the ball for the 23 th exchange
    ping received the ball for the 24 th exchange
    3> pingpong:stop(P1).
    stop
    4> pingpong:stop(P2).
    stop
    5>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?