Können IDS werden dupliziert, über die Fälle der Variante record in FreePascal?
Hier ist mein problem: ich möchte ein record-Typ, wo unter den Fällen der Variante record, einige, aber nicht alle, haben einen bestimmten Bereich. Nach der wiki, ist dies vollkommen legal. Und doch, wenn ich versucht zu kompilieren, den folgenden code:
program example;
{$mode objfpc}{$H+}
uses sysutils;
type
maritalStates = (single, married, widowed, divorced);
TPerson = record
name: record
first, middle, last: string;
end;
sex: (male, female);
dob: TDateTime;
case maritalStatus: maritalStates of
single: ( );
married, widowed: (marriageDate: TDateTime);
divorced: (marriageDate, divorceDate: TDateTime;
isFirstDivorce: boolean)
end;
var
ExPerson: TPerson;
begin
ExPerson.name.first := 'John';
ExPerson.name.middle := 'Bob';
ExPerson.name.last := 'Smith';
ExPerson.sex := male;
ExPerson.dob := StrToDate('05/05/1990');
ExPerson.maritalStatus := married;
ExPerson.marriageDate := StrToDate('04/01/2015');
end.
schlägt die Kompilierung fehl mit der folgenden Fehlermeldung:
$ fpc ex.pas
Free Pascal Compiler version 3.0.0 [2016/02/14] for x86_64
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling ex.pas
ex.pas(19,18) Error: Duplicate identifier "marriageDate"
ex.pas(21,3) Error: Duplicate identifier "marriageDate"
ex.pas(35,4) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted
Error: C:\lazarus\fpc\3.0.0\bin\x86_64-win64\ppcx64.exe returned an error exitcode
Ist das wiki einfach falsch, oder bin ich hier etwas fehlt? Gibt es eine Möglichkeit, um diesen Effekt zu erzielen, die ich will?
- Genial! Das klappte! Möchten Sie dies als Antwort, damit kann ich markierte die Frage gelöst, oder willst du mir es beantworten?
- Wiki ist les-und schreibbar für alle, die sich registriert, und ist nicht MAßGEBEND. Es sind keine FPC-Menschen, die in der Liste der Mitwirkenden zu dieser Seite. Es könnte auch getan werden, indem sb mit einem anderen Modus (.e.g ISO-oder Macpas).
- FWIW, ISTM, dass die Menschen können geschiedene und verwitwete oder verheiratet. Oder alle diese. Sie können auch geschieden und single. <g>
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sehr interessante Frage. Ich war sicher, dass dies möglich ist. Wenn Sie Ihren code so abändern:
es funktioniert, aber es ist nicht das Ergebnis, das Sie haben möchten. Da marriageDate und die divorceDate überlagern einander (wie erwähnt in den Kommentaren!)
Diesem Bild ist entnommen aus "Pascal-Benutzer-Handbuch (4. Auflage)" und wie sehen Sie die Variante, die Teile haben die gleiche Speicherposition.
Laut Pascal-Benutzer-Handbuch (4. Auflage) und zu dem Buch "Turbo Pascal ISBN 3-89011-060-6 dem beschriebenen record-Deklaration auf Ihr Angebot wiki ist nicht gültig!
Punkt 1 ist das relevant hier! Das Buch "Turbo Pascal" ist die vorgeschlagene Lösung verwenden Sie ein eindeutiges Präfix für die Feld-Namen, die mehrfach vorkommen.
In Ihrem Fall Ihren konnte würde wie folgt Aussehen:
Die andere Lösung wäre zu definieren, verheiratet, devorced ... als record-Typ.
marMarriageDate
undvidMarriagedate
überlappen, also warum nicht einfach einmarriageDate
ist nicht - Variante? Die Tatsache, dasssingle
brauchen nicht, eine Ehe Datum spielt keine Rolle. Benutzen Sie es einfach nicht. Und die Datensatz-Größe wird genau das gleiche sowieso.Diese scheint zu funktionieren
EDIT: Man könnte auch definieren, die die Datensätze inline, aber die oben ist klarer, denke ich. Hier ist die alternative:
marriageDate
mandivorcedDate
etc.m.
,w.
oderd.
. Beachten Sie, dass allemarriageDate
Felder Ihres Datensatzes überschneiden sich sowieso. Also noch einmal: warum so kompliziert?marriageDate
deckt alle von Ihnen, da Sie alle überlappen. und die extra-Felder müssen nicht sein, Variante entweder. Versuchen Sie es.w.marriageDate
,m.marriageDate
undd.marriageDate
in Ihrem Datensatz haben alle den gleichen offset ist der gleiche wie der Versatz dermarriageDate
in meinem nicht-variant-record. Und die folgenden Felder haben natürlich die gleichen hohen offsets, genau das gleiche wie in meiner nicht-Variante aufnehmen. Variante records sicherlich Sinn machen, aber in diesem Fall nicht.Was Baltasar schlägt kompiliert wird, aber nicht tun, was Sie wollen.
marriageDate
unddivorceDate
überlappen und schreiben zu einem von Ihnen ändern auch die anderen, denn Sie sind einfach an die gleiche Adresse.Aber in diesem Fall gibt es keinen guten Grund für eine Variante aufnehmen.
Warum nicht einfach:
Die Benutzung und das layout ist genau das, was Sie brauchen. Wenn ein Feld nicht anwendbar (z.B.
marriageDate
für einesingle
oderdivorceDate
für einemarried
), die Sie einfach nicht verwenden.Identisch ist mit einer Variante record. Dort gibt es auch nur die Felder, die angewendet werden. Beachten Sie, dass der compiler oder Laufzeit nicht verhindern, dass Sie vom schreiben auf das falsche Feld einer Variante record sowieso, also in einer Variante aufnehmen, wenn der status
single
können Sie noch schreiben oder Lesen vondivorceDate
, auch wenn das keinen Sinn macht.Wenn Sie unterscheiden wollen verschiedene setups, einfach das zu tun in den Kommentaren, und vergesst die Variante aufnehmen, Sie brauchen es nicht hier. Jetzt können Sie tun:
Update
Nur um zu zeigen, dass es absolut keine Notwendigkeit, diese Platte Variante,
Werde ich nach meinem Project62.dpr, der zeigt genau die gleichen offsets für die entsprechenden Felder ein und denselben Datensatz-Größen:
Ausgabe (unter Windows):
Layout in 32 bit kann gesetzt werden, um ein einfaches Diagramm, in etwa so: