2016-06-21 39 views
7

mam ten wiersz:zestaw WideChar: Zestawy mogą mieć co najwyżej 256 elementów

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

Powyższe nie kompilacji, z powodu błędu:

[Error] Sets may have at most 256 elements

Ale ta linia ma skompilować ok:

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

I zestawia również oK:

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

Dlaczego tak jest?

EDIT: Moje pytanie brzmi dlaczegoif WS[1] in [WideChar('A')..WideChar('Z')] kompiluje? i dlaczego kompiluje się MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];? czy nie muszą również stosować się do zasad set?

+0

Drugi kod ma tylko 26 elementów. Znacznie prostsze w użyciu> = i <= tutaj. Zwróć uwagę, że twój kod nie uznaje znaków nieangielskich. –

+0

@ David: Czy pierwszy kod nie zawiera również 26 elementów? "Zauważ, że twój kod nie uznaje znaków nieangielskich." Muszę sprawdzić poprawne znaki ISO. ważne są tylko angielskie znaki. – zig

+1

Tak długo, jak same elementy są poniżej 256, drugie wyrażenie jest poprawne. Pierwsze wyrażenie deklaruje zbiór większy niż 256 (zestaw WideChar). –

Odpowiedz

11

Poprawny zestaw musi przestrzegać dwóch zasad:

  1. Każdy element w zestawie musi mieć wartość porządkową mniej niż 256.
  2. Zestaw nie może zawierać więcej niż 256 elementów.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 

Tutaj zadeklarować zestaw typ (Set of WideChar), który ma więcej niż 256 elementów -> Błąd kompilatora.

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

Tutaj kompilator widzi WideChar('A') jako wartość porządkową. Ta wartość i wszystkie pozostałe wartości w zestawie są mniejsze niż 256. Jest to zgodne z zasadą 1.

Liczba unikatowych elementów mieści się również w granicach (Ord ("Z") - Ord ("A") + 1) , więc druga zasada przechodzi.

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

Tutaj deklarujesz zestaw, który spełnia również powyższe wymagania. Zauważ, że kompilator widzi to jako zbiór wartości porządkowych, a nie jako set of WideChar.

+1

Interesujące, w drugim przypadku (jeśli WS [1] w ,,,), jak dokonuje porównania? –

+0

@TomBrunberg, nie ma żadnej różnicy poza tym, że kompilator używa rozmiaru lewego parametru w porównaniu z elementem zestawu rozmiaru bajta. –

+1

@zig Tak więc błąd występuje w części * MY_SET: zestaw części WideChar *, a nie w * [WideChar ("A") .. WideChar ('Z')] * –

2

Zestaw może mieć nie więcej niż 256 elementów.
Nawet przy tak niewielu elementach zestaw już używa 32 bajtów.

Z dokumentacji:

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

Z tego powodu tylko zestawy bajta, są możliwe (ANSI) char, boolean i wyliczenia z mniej niż 257 elementów.
Ponieważ widechar używa 2 bajtów, może mieć 65536 możliwych wartości.
Zestaw widechar zajmowałby 8Kb, zbyt duży, aby był praktyczny.

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

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

Skompiluje i będzie działać tak samo.

Używanie widechar wydaje się nieco głupie, jeśli Twój kod ignoruje kod Unicode.
Jak pisano tylko angielskie litery są rozpoznawane, nie bierzesz pod uwagę różnych ustawień regionalnych.

W tym przypadku lepiej byłoby użyć kodu jak

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

który będzie działał bez względu na to jak wiele znaków spadek pomiędzy.
Oczywiście można zamknąć to w funkcji, aby zaoszczędzić na pisaniu.

Jeśli domagać się dużych zestawów, zobacz tę odpowiedź: https://stackoverflow.com/a/2281327/650492

+2

Ale dlaczego 'jeśli WS [1] w [WideChar (" A ") .. WideChar (" Z ")]' kompiluje? i dlaczego "MY_SET = [WideChar (" A ") .. WideChar (" Z "), WideChar (" a ") .. WideChar (" z ")];" kompiluje? czy nie mają one również zastosowania do zasad "zestawienia"? jaka jest różnica? – zig

+4

Kompilator konwertuje 'WideChar ('A')' na wartość porządkową, która jest mniejsza niż 256. Jeśli wstawisz wartość większą niż ta, kompilator będzie narzekał. Teraz kompilator ma poprawny zestaw z elementami Ord ("Z") - Ord ("A") +1. –