2016-06-21 3 views
7

У меня есть эта строка:набор WideChar: Наборы могут иметь не более 256 элементов

const 
    MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 

выше не компилируется с ошибкой:

[Error] Sets may have at most 256 elements

Но эта линия компилируется нормально:

var WS: WideString; 
if WS[1] in [WideChar('A')..WideChar('Z')] then... 

И это также компилирует ОК:

const 
    MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; 
    ... 
    if WS[1] in MY_SET then... 

Почему?

EDIT: Мой вопрос почемуif WS[1] in [WideChar('A')..WideChar('Z')] компилирует? и почему компилируется MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];? не должны ли они также применяться к правилам set?

+0

Второй код имеет только 26 элементов. Намного проще использовать> = и <= здесь. Обратите внимание, что ваш код не распознает неанглийских символов. –

+0

@ Давид, не первый код имеет также 26 элементов? «Обратите внимание, что ваш код не распознает неанглийских символов». Мне нужно проверить допустимые символы ISO. действительны только английские символы. – zig

+1

Пока элементы сами находятся ниже 256, действует второе выражение. Первое выражение объявляет набор размером более 256 (набор WideChar). –

ответ

11

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

  1. Каждый элемент в наборе должен иметь порядковое значение меньше, чем 256.
  2. Набор не должен содержать более 256 элементов.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 

Здесь вы объявляете типа набора (Set of WideChar), который имеет более чем 256 элементов -> ошибка компилятора.

if WS[1] in [WideChar('A')..WideChar('Z')] 

Здесь компилятор видит WideChar('A') как порядковое значение. Это значение и все остальные значения в наборе ниже 256. Это нормально с правилом 1.

Число уникальных элементов также находится в пределах (Ord ('Z') - Ord ('A') + 1) , поэтому проходят 2-е правила.

MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; 

Здесь вы объявляете комплект, который также выполняет требования, как указано выше. Обратите внимание, что компилятор видит это как набор порядковых значений, а не как set of WideChar.

+1

Интересно, во втором случае (если WS [1] in ,,,), как это сделать сравнение? –

+0

@TomBrunberg, нет никакой разницы, кроме того, что компилятор использует размер левого параметра в сравнении с элементом набора размера байта. –

+1

@zig Таким образом, ошибка в * MY_SET: набор части WideChar *, а не в * [WideChar ('A') .. WideChar ('Z')] * –

2

Набор может иметь не более 256 элементов.
Даже с таким количеством элементов набор уже использует 32 байта.

Из документации:

A set is a bit array where each bit indicates whether an element is in the set or not. The maximum number of elements in a set is 256, so a set never occupies more than 32 bytes. The number of bytes occupied by a particular set is equal to

(Max div 8) - (Min div 8) + 1

По этой причине только наборы байт, (ANSI) символ, логические и перечисления с менее чем 257 элементов возможны.
Поскольку widechar использует 2 байта, он может иметь 65536 возможных значений.
Набор широкоформатных будет занимать 8Kb, слишком большой, чтобы быть практичным.

type 
    Capitals = 'A'..'Z'; 

const 
    MY_SET: set of Capitals = [WideChar('A')..WideChar('Z')]; 

Будет компилироваться и работать одинаково.

Кажется, немного глупо использовать широкоформатный, если ваш код игнорирует unicode.
Как указано, только английские столицы признаются, вы не учитываете разные локали.

В этом случае было бы лучше использовать код, как

if (AWideChar >= 'A') and (AWideChar <= 'Z') .... 

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

Если вы настаиваете на большие наборы, см этот ответ: https://stackoverflow.com/a/2281327/650492

+2

Но почему '' если WS [1] в [WideChar ('A') .. WideChar ('Z')] 'компилируется? и почему 'MY_SET = [WideChar ('A') .. WideChar ('Z'), WideChar ('a') .. WideChar ('z')];' компилирует? не являются ли они также применимыми к правилам 'set'? в чем разница? – zig

+4

Компилятор преобразует 'WideChar ('A')' в порядковое значение, которое меньше 256. Если вы добавите значение, большее, чем это, компилятор будет жаловаться. Теперь у компилятора есть действительный набор с элементами Ord ('Z') - Ord ('A') +1. –