2014-09-30 62 views
1

開始使用Erlang的工作最近相當及以上的跑進了問題,你怎麼去有關保護聲明比較兩個字符串?嘗試了字符串:equal(x,y)方法,但無法使其在警衛內工作。二郎:匹配字符串中後衛聲明

回答

4

你不需要的功能string:equal/2比較字符串;您可以使用在警衛測試中允許的運營商===:=。例如:

foo(A, B) when A =:= B -> 
    equal; 
foo(_, _) -> 
    not_equal. 

雖然在大多數情況下,你想使用模式匹配代替,如other answer描述。

+0

哦,「=:=」沒有奇蹟。非常感謝! – 2014-09-30 17:11:22

3

您可以在警衛使用該功能的,因爲Erlang的調度性質的限制;具體而言,Erlang的目標是避免警戒語句中的副作用(例如,調用另一個進程),因爲警衛是由調度程序評估的並且不計入削減。這就是爲什麼string:equal不起作用。

話雖這麼說,你可以使用Erlang的模式匹配來匹配字符串。請記住在Erlang中使用字符串作爲列表,二進制文件或iolists(嵌套列表/二進制文件),並確保您正在測試/傳遞正確類型的字符串(iolists特別難以模式匹配,通常是最好的使用re模塊處理,或通過iolist_to_binary將它們轉換爲二進制文件)。

例如,假設我們想要一個測試,看是否有字符串爲「foo」開頭的函數:

bar("foo" ++ _Rest) -> true; 
bar(<<"foo", Rest/binary>>) -> true; 
bar(_Else) -> false. 

如果你只是想測試一個特定的字符串,那就更簡單了:

bar("foo") -> true; 
bar(<<"foo">>) -> true; 
bar(_Else) -> false. 
+0

@legoscia答案,解決了這個問題,但如果你不介意的話:你會如何樣式反對另一個變量使用此匹配的變量方法? <<_, _>>表達式究竟幹什麼? – 2014-09-30 17:20:13

+1

不幸的是,模式匹配的侷限之一正是你所描述的:你不能將另一個變量與列表或二進制匹配(例如,既不是'bar(Test ++ _Rest,Test)'也不是'bar(<< Test/binary,_Rest/binary >>,Test)'會工作)。在匹配整個變量時,@ legoscia的解決方案是最好的。如果你正在尋找部分匹配,你將不得不綁定你在函數聲明中測試的變量,並使用case語句聲明匹配。 – 2014-09-30 18:28:50

+1

和<<_,_>>,除非我錯了,否則匹配一個雙字節二進制。 – 2014-09-30 18:29:59

7

你可以使用模式這樣的匹配:

are_the_same(A, A) -> 
    true; 
are_the_same(_, _) -> 
    false. 

在第一條兩個參數被命名爲A,這將導致他們成爲互相匹配的模式。或者準確的說第一個參數將被綁定到與使用=運營商的A變量,而且比第二個參數將被綁定到A變量與=運營商,但由於A已經被綁定,將被視爲「比較」。你可以閱讀more about this in docs

當然,你可以寫寫第一克勞斯與使用保護的,如:

are_the_same(A, B) when A =:= B ->