如果在handle_call函数中有“record = State”会发生什么?

时间:2012-03-31 08:29:09

标签: erlang gen-server

gen_server中的handle_call函数是:

Module:handle_call(Request, From, State) -> Result

但是我遇到了一个这样的handle_call函数:

handle_call(info, _From, #yuv{decoder = undefined} = State) ->
  {reply, [], State};

handle_call(info, _From, #yuv{decoder = Decoder} = State) ->
  {reply, av_decoder:info(Decoder), State};

handle_call(_Request, _From, State) ->
  {noreply, ok, State}.

我想知道发生了什么?它超越了我的头脑

BTW:yuv记录是:

-record(yuv, {
  host,
  name,
  media,
  decoder,
  consumer
}).

2 个答案:

答案 0 :(得分:6)

如果我理解你的问题,你就不明白以下模式的作用:

foo(#bar{buz = Value} = Record) -> ...

这是对函数参数的整体和部分进行模式匹配的常用方法。在我的示例中,变量Value将保存字段buz的值,变量Record将保存整个记录的值。这可以应用于其他情况,例如:

foo([Head|Tail] = List) -> ...
foo({First, Second} = Tuple) -> ...

等等。您可以使用文字而不是变量,只有在调用中出现相同的文字时,模式匹配才会成功。

在你的例子中:

handle_call(info, _From, #yuv{decoder = undefined} = State) ->
  {reply, [], State};

handle_call(info, _From, #yuv{decoder = Decoder} = State) ->
  {reply, av_decoder:info(Decoder), State};

handle_call(_Request, _From, State) ->
  {noreply, ok, State}.

如果decoder字段的值为undefined,则第一个模式匹配,然后回复为[]。第二个匹配decoder的所有其他情况,并使用函数返回的值进行回复。在这两种情况下,State都没有被修改,并且“按原样”传递回内部gen_server处理程序。

答案 1 :(得分:1)

如果记录yuv定义为:

-record(yuv, { decoder, foo, bar, baz }).

形式:

handle_call(info, _From, #yuv{decoder = undefined} = State) -> {reply, [], State};

只是糖:

handle_call(info, _From, {yuv, undefined, _, _, _} = State) -> {reply, [], State};

函数头部的匹配正是你所期望的,它只是试图将函数头中定义的记录与记录State wh

匹配。