2016-06-21 18 views
7

Ich habe diese Zeile:Satz von WideChar: Sets können höchstens 256 Elemente

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

Die oben nicht kompilieren, mit Fehler:

[Error] Sets may have at most 256 elements

Aber diese Linie ok nicht kompiliert:

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

Und das stellt auch ok:

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

Warum ist das?

EDIT: Meine Frage ist, warum if WS[1] in [WideChar('A')..WideChar('Z')] compiliert? und warum MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; kompiliert? Müssen sie nicht auch auf die set Regeln angewendet werden?

+0

Der zweite Code hat nur 26 Elemente. Viel einfacher zu verwenden> = und <= hier. Beachten Sie, dass Ihr Code nicht englische Zeichen nicht anerkennt. –

+0

@David, Hat der erste Code nicht auch 26 Elemente? "Beachten Sie, dass Ihr Code nicht englische Zeichen nicht anerkennt." Ich muss gültige ISO-Zeichen überprüfen. Nur englische Zeichen sind gültig. – zig

+1

Solange die Elemente selbst unter 256 sind, ist der zweite Ausdruck gültig. Der erste Ausdruck deklariert eine Menge, die größer als 256 ist (WideChar-Menge). –

Antwort

11

Ein gültiger Satz hat zwei Regeln zu befolgen:

  1. Jedes Element in einem Satz muss einen Ordnungswert weniger hat als 256.
  2. Der Satz darf nicht mehr als 256 Elemente enthalten.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 

Hier deklarieren Sie eine Settyps (Set of WideChar), die mehr als 256 Elemente hat -> Compilerfehler.

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

Hier wird der Compiler sieht WideChar('A') als Ordnungswert. Dieser Wert und alle anderen Werte im Satz liegen unter 256. Dies ist mit Regel 1 in Ordnung.

Die Anzahl der Einzelelemente liegt ebenfalls innerhalb der Grenzen (Ord ('Z') - Ord ('A') + 1) , so vergeht die 2. Regel.

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

Hier deklarieren Sie einen Satz, der auch die oben genannten Anforderungen erfüllt. Beachten Sie, dass der Compiler dies als eine Reihe von Ordinalwerten sieht, nicht als set of WideChar.

+1

Interessant, im zweiten Fall (wenn WS [1] in ,,,), wie macht es den Vergleich? –

+0

@TomBrunberg, gibt es keinen Unterschied neben dem verwendet der Compiler die Größe des linken Parameters im Vergleich mit einem Byte-Size-Set-Element. –

+1

@zig Also der Fehler ist in der * MY_SET: Set von WideChar * Teil, nicht in der * [WideChar ('A') .. WideChar ('Z')] * –

2

Ein Satz darf nicht mehr als 256 Elemente enthalten.
Selbst mit so wenigen Elementen verwendet das Set bereits 32 Bytes.

Aus der Dokumentation:

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

Aus diesem Grunde nur Sätze von Byte, (ANSI) char, boolean und Aufzählungen mit weniger als 257 Elementen sind möglich.
Da widechar 2 Bytes verwendet, kann es 65536 mögliche Werte haben.
Eine Reihe von widechar würde 8KB, zu groß, um praktisch zu sein.

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

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

Kompiliert und funktioniert das gleiche.

Es scheint ein bisschen albern, widechar zu verwenden, wenn Ihr Code Unicode ignoriert.
Wie geschrieben, werden nur die englischen Großbuchstaben erkannt, unterschiedliche Gebietsschemata werden nicht berücksichtigt.

In diesem Fall wäre es besser, den Code zu verwenden, wie

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

, dass egal funktionieren, wie viele Zeichen fallen dazwischen.
Offensichtlich können Sie dies in einer Funktion kapseln, um beim Tippen zu sparen.

Wenn Sie mit großen Sätzen bestehen, sehen Sie diese Antwort: https://stackoverflow.com/a/2281327/650492

+2

Aber warum 'wenn WS [1] in [WideChar ('A') .. WideChar ('Z')]' kompiliert? und warum 'MY_SET = [WideChar ('A') .. WideChar ('Z'), WideChar ('a') .. WideChar ('z')];' kompiliert? Gilt das nicht auch für die Set-Regeln? Was ist der Unterschied? – zig

+4

Der Compiler konvertiert 'WideChar ('A')' in einen Ordinalwert, der kleiner als 256 ist. Wenn Sie einen größeren Wert eingeben, wird der Compiler beschweren. Jetzt hat der Compiler eine gültige Menge mit Ord ('Z') - Ord ('A') +1 Elementen. –