让我们看看Java编程语言(作为一个例子),如果我想创建一个概念消息应用程序,它看起来就像这样:
class User {
static List<User> users = new ArrayList();
String name;
User(String name) {
this.name = name;
users.add(this);
}
void sendMessage(String message) {
for(User user : users) {
user.messageReceived(message);
}
}
void messageReceived(String message) { System.out.println(message); }
String getName() { return name; }
}
上面的代码只是为了说明如何使用多个可以相互通信的对象。
您可以执行以下操作来创建用户并发送消息:
User bob = new User("Bob");
User john = new User("John");
User anne = new User("anne");
bob.sendMessage("Hello World!");
所有已创建的用户都会收到bob的消息。
我正在尝试学习Erlang,并尝试重新创建这种类似的应用程序。我希望能够让不同的用户相互通信。
我尝试过很多东西:
-module(test).
-export([sendMessage/1]).
sendMessage(M) ->
io:format(M, []).
这样做只是将消息打印到控制台。我怎样才能拥有多个用户?
是否有某种模式或其他事情要做?
感谢您的时间:)
答案 0 :(得分:2)
在你找到正确的入口点之前开始使用erlang并不容易,所以,虽然你的问题在我看来不是主题,但我会尝试给你一些信息和评论。
首先我建议您访问网站LearnYouSomeErlang,这是一个非常好的资源,可以使用真正的逐步方法开始使用erlang和函数式编程。我认为投资非常有价值,至少对我来说是这样。
下一步我已经评论了您的代码,并考虑了应该为erlang实现所做的更改。
class User {
Erlang中没有类概念,也没有对象。基本元素是一个进程(一个轻量级进程,完全独立于底层操作系统进程)。每个过程都有一个生命周期,在其生命周期中它能够维持一个状态。 这个状态可能是任何erlang术语,一旦进程死亡就会丢失。
static List<User> users = new ArrayList();
没有静态全局变量。维护一条信息的唯一方法是将其存储在进程状态, 显式地通过将状态作为服务器循环的参数传递,或者通过使用某些特殊存储(例如ETS或mnesia数据库)隐式地传递。 因此,要拥有包含用户名列表的内容,您需要,例如,注册为name_server的服务器进程在其状态中保存用户名列表。 在大多数情况下,应用程序确保在启动任何客户端之前启动所有必需的服务器。
String name;
流程能够维护信息。流程的基本结构是
和一个循环,它主要包含一个分析传入消息的接收块,根据收到的消息调用一些辅助函数,并通过调用自身以更新状态递归循环。
用户(字符串名称){ this.name = name; users.add(本); }
构造函数由2个函数start和init替换。启动函数在OOP中没有真正的等价,除了它依赖于系统为内部数据,消息队列,堆栈分配必要的内存......与java或C ++中对象属性的自动内存分配相当。然后,它在VM调度程序中注册该进程。 init等同于用户定义的构造函数。
void sendMessage(String message) {
for(User user : users) {
user.messageReceived(message);
}
}
以这种方式编写,sendMessage函数不依赖于它在执行时所属的对象实例,因为它只使用类的静态数据。因此,最接近的转换可以是名称服务器的接口。接口通常是属于服务器模块(相同文件!)的代码段,为其他模块导出,并在客户端进程上下文中执行。接口向服务器发送消息(其主要作用是隐藏与服务器的通信协议),如果访问是同步的(或不是),则等待响应(或不响应)。在真实的通信应用程序中,请求应来自用户,由系统中的进程表示,并且流程看起来更像:
也可以使用名称服务器直接发送消息
void messageReceived(String message) { System.out.println(message); }
String getName() { return name; }
这两个最后的函数是用户进程中的辅助函数,它们在消息接收时触发。
最后,如果您有兴趣,我在github minichat上放了一个聊天系统示例,这个示例相当简单,并说明了此处讨论的所有内容(以及更多内容)并包括文件和评论。
答案 1 :(得分:0)
-module(chat).
-export([new/1, delete/1, send/3]).
-export([init_user/1]).
new(UserName)->
spawn(?MODULE, init_user, [UserName]).
delete(Pid)->
Pid ! stop.
send(From, To, Message)->
To ! {message, From, Message}.
init_user(UserName)->
io:format("Starting Client ~w with user name ~w~n",[self(), UserName]),
wait_for_message(UserName).
wait_for_message(UserName)->
receive
{message, From, Message}->
io:format("Got Message From ~w And Message: ~s~n",[From, Message]),
wait_for_message(UserName);
stop->
io:format("Stoping~w~n",[self()]);
Message->
io:format("Unhandled Message:~w~n",[Message]),
wait_for_message(UserName)
end.
模拟进程间的通信示例: -
c(chat).
Bob = chat:new("Bob").
John = chat:new("John").
Anne = chat:new("Anne").
chat:send(Bob, John, "Hello World!!").