Исправить использование оператора

Рассмотрим следующую процедуру

procedure InTests;
var
  N, K: Integer;

begin
  N:= 1111;
  if N in [6, 8, 10]          // this is correct, readable and effective code
    then ShowMessage('OK');

  K:= 11;
  if N in [6, 8, 10, K]       // this is correct but less effective
    then ShowMessage('OK');   //  (compiler creates local 16-bytes set var)

  K:= 1111;
  if N in [6, 8, 10, K]       // this is a bug (K > 255)
    then ShowMessage('OK');
end;

in вместо if chain

  if (N = 6) or (N = 8) or (N = 10)
    then ShowMessage('OK');

делает код более компактным и читаемым, но документация Delphi об этом молчат, и вы должны знать о потенциальных проблемах.

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

  if N in [6, 8, 10]
    then ShowMessage('OK');

считается хорошей практикой в ​​Delphi?

Ответ 1

Это определенно хорошая практика. Это делает код более читаемым и устраняет необходимость в логических операторах, круглых скобках и т.д. Я бы всегда использовал in для такого теста.

Единственным недостатком является очень ограниченная поддержка Delphi sets (базовый порядковый тип может иметь не более 256 значений). Но там, где вы не связаны этими ограничениями, вы не должны колебаться при использовании in.

Ответ 2

У вас есть set of byte. Вопрос, который вы должны задать себе, - это действительно ли set of byte то, что представляют ваши цифры? Здесь у вас "магические числа", и, хотя я понимаю, что это всего лишь образец, вы должны учитывать, что

 if Token in [TokenString, TokenNumber, TokenChar] then

... будет считаться хорошей практикой, это:

 if N in [2, 12, 14, 19] then

... не будет.

Однако в первом случае (с именем tokens) явный тип набора будет гораздо более эффективной:

 type TokenSet = ( TokenNone, TokenString, TokenChar,... )

Тогда первый образец является окончательно хорошей практикой.