2

gen_server 中的 handle_call 函数是:

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

但是我遇到了一个这样的handle_call函数:</p>

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}.

我想知道发生了什么?它在我头顶

顺便说一句:yuv 记录是:

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

2 回答 2

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 处理程序。

于 2012-03-31T10:12:02.280 回答
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};

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

于 2012-03-31T18:29:19.493 回答