2010-03-23 76 views
3

我試圖在衛兵中使用記錄,如此處所述[1]。如果我使用有描述的縮寫形式:衛兵的記錄

handle(Msg, State) when Msg==#msg{to=void, no=3} -> 

...我從來沒有一場比賽......但是,如果我把它完全擴展爲:

handle(Msg, State) when Msg#msg.to==void, Msg#msg.no==3 -> 

...一切都很好。就像我對大多數erlang文檔所做的那樣,我讀錯了嗎?

感謝, --tim

[1] - http://www1.erlang.org/doc/reference_manual/records.html#id2278275

+3

只是一種猜測,但你的第一個匹配假定記錄中沒有其他字段或所有其他字段都設置爲未定義。 如果msg記錄有其他字段會導致它失敗。 – 2010-03-23 17:29:45

+0

謝謝傑里米,那一定是(還有其他有價值的領域),我認爲它們在語義上是等價的。再次感謝...... – Tim 2010-03-23 17:35:27

+0

就像進一步的注意事項一樣,您可以使用函數簽名中的模式匹配來完成此操作。這場比賽失敗了,因爲它進行了平等測試。您可能已被視覺相似度==爲平等和=在模式匹配中的綁定絆倒。 – 2010-03-23 20:42:44

回答

11

當你在警衛中說#msg{to=void, no=3}時,所有未提及的字段將被設置爲其默認值(通常爲undefined)。所以你的警衛不能匹配,因爲一些未列出的字段不匹配。

handle(Msg = #msg{to=void, no=3}, State) -> 
    ... 

此模式需要消息味精記錄(一個元組的MSG記錄與大小:

我傾向於在可能一直使用的模式,而不是一個組織後衛,所以我會爲寫條款第一個元素是msg),to元素必須是void而且no元素必須是3. msg記錄的其他元素可以是任何內容。

+0

謝謝大家,正如所有人都猜測,我應該使用一種模式,而不是...這種學習曲線陡峭,但愉快...再次感謝... – Tim 2010-03-24 11:04:49

4

我看你已經解決了這個問題。只是注意:在地道二郎你平時寫的比賽是這樣的:

handle(Msg = #msg{to = void, no = 3}, State) -> 

當然,它涉及到的味道,有時你需要使用看守,而不是獲得更加賞心悅目線對齊。

4

您可能需要使用以下方式來代替,其簡潔

handle(#msg{to=void, no=3}=Msg, State) -> 
    do_stuff(Msg). 

如果您不需要整個味精記錄值,但是在它只有一些字段,則可以匹配和破壞這樣

handle(#msg{to=void, no=3, data=Data}, State) -> 
    do_stuff(Data). 
0

當匹配記錄很大時,匹配記錄可能會很麻煩。我處理這個問題的方法是通過測試記錄的第一個元素,它應該是記錄名稱:

手柄(不管)時,元件(1,MSG)==味精