Эрланг стиль - случай против сопоставления с образцом функции - PullRequest
19 голосов
/ 26 июня 2009

Я дошел до стадии, когда я написал довольно много кода на Erlang, и я вижу, как какой-то стиль (плохой или хороший) вкрадывается в то, как я его пишу. Именно об этой идиоме мне хотелось бы получить какое-то мнение о том, лучше ли (более читабельно / быстрее / безотносительно) преобразовывать операторы в стиле case в сопоставление с шаблоном функции?

* 1003 Е.Г. *

Сравнить (надуманный пример)

case {Size > 100000, Type} of
    {true, ets } ->
         %% Do something to convert to dets
         something;
    {false, dets} ->
         %% do something to convert to ets
         somethingelse;
    _ ->
         ignoreit
end;

с

...
maybeChangeStorage(Size, Type)
...

maybeChangeStorage(Size, ets) when Size > 10000 ->
   something;
maybeChangeStorage(Size, dets) when Size < 10000 ->
   somethingelse;
maybeChangeStorage(_,_) ->
   ignoreit.

Я предпочитаю последнее в большинстве случаев, но мне было бы интересно другое мнение.

Ответы [ 6 ]

14 голосов
/ 27 июня 2009

Второй способ предпочтителен, особенно если вы можете сохранить пункты в одну строку:

maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse;
maybeCngStor(_,_)                      -> ignoreit.

Делает это очень легко читать и рассуждать о. Всегда выбирайте стиль, который будет легче читать в будущем. Часто вы найдете набор предложений, где один - 10 строк, а остальные - только в одной строке - выделите длинную функцию:

maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse();
maybeCngStor(_,_)                      -> ignoreit.

somethingelse() ->
   (...)
   Return.

Маленькие вещи, такие как выкладывание предложений для их выравнивания и использование коротких имен переменных, имеют значение - но не попадайтесь в ловушку изменения всего на P, Q, R.

Хорошая уловка, если вы часто используете записи, это сопоставлять записи с короткими переменными:

#record{foo = F, bar = B, baz = Bz} = Parameter

Это дает вам короткие имена переменных, которые имеют смысл, когда вы прыгаете в функцию с 10 000 футов в поисках ошибки на следующее Рождество. F, очевидно, является Foo, и т.д, и т.д ...

7 голосов
/ 04 января 2013

Узнайте, какой Erlang для хорошего блага имеет небольшую секцию , когда выбрать case и когда использовать function. Упоминаются две вещи:

  1. Они одинаково представлены в ВМ, поэтому нет разницы в производительности между двумя решениями.

  2. Если вам нужно использовать защиту от более чем одного аргумента, использование функции может показаться лучше.

В целом, это в основном вопрос стиля и вкуса.

3 голосов
/ 27 июня 2009

Вы можете сделать эти примеры более похожими, выполнив:

case Type of
   ets  when Size > 10000 -> ...;
   dets when Size < 10000 -> ...;
   _ -> ...
end.

Это кажется мне более понятным. Преимущество разделения этой функции на отдельную функцию состоит в том, что вы можете дать ей имя, которое действует как документация и появляется в следах стека. Если этот фрагмент является частью более крупной функции, я бы выделил его, иначе все в порядке, как есть.

Стоит учесть одну вещь: в случае ошибки, как написано, функция будет принимать аргументы типа, отличные от ets / dets. Если это действительно то, чего вы хотите, стоит сделать этот пункт более ограничительным.

0 голосов
/ 20 мая 2011

Если в вашей функции первым делом вы открываете предложение case, лучше преобразовать это предложение верхнего уровня в сопоставление с образцом функции.

0 голосов
/ 02 июля 2009

(Поставьте в качестве ответа, чтобы получить форматирование кода ...!)

Одна вещь, которую я обнаружил, когда вносил некоторые изменения, это что этот подход может изменить замыкание по умолчанию. Например.

case A > 10 of 
      true -> 
             case B > 10 of 
                  true -> dummy1; 
                  false -> dummy2 
             end; 
      false -> dummy3 
end 

всегда будет выполнять B> 10, если вы называете это как

doTest(A > 10, B > 10) 

когда

doTest(true, true) -> dummy1; 
doTest(true, false) -> dummy2; 
doTest(false, _) -> dummy3. 

что иногда не то, что вы хотите!

0 голосов
/ 27 июня 2009

На мой взгляд, первый стиль более понятен и может быть быстрее. Но это нужно проверить, чтобы сказать это точно. Во втором случае, если type! = Ets, то будут оцениваться и "Size> 10000", и "Size <10000". </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...