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
}).
答案 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