delphi - programación - Las constantes anidadas de tipos estructurados anidados no son compatibles?
delphi wikipedia (2)
A pesar de lo que dice la referencia de Delphi
los tipos estructurados pueden contener otros tipos estructurados; un tipo puede tener niveles ilimitados de estructuración
con notable excepción, qué constantes tipadas estructuradas
no puede contener valores de tipo de archivo en cualquier nivel
Descubrí que no puedo usar la constante de grabación como un elemento constante de matriz del mismo tipo.
Caso de prueba
type
MyRecord = record MyField: Integer end;
const
Typical: array[0..1] of MyRecord = ((MyField: 0), (MyField: 1));
{ now I tried to achieve more clarity by declaring a specific constant }
Zero: MyRecord = (MyField: 0);
{ and compiler refused to accept that }
Bad: array[0..1] of MyRecord = (Zero, (MyField: 1)); { E2029 ''('' expected but identifier ''Zero'' found }
Probé este código con varios compiladores de Borland, todos exhibieron el mismo comportamiento. UPD: también lo mismo para FPC, pero no para GPC (!).
Pregunta (s)
¿Que esta pasando aqui? ¿Estoy en lo correcto con las "constantes anidadas de tipos estructurados anidados no son compatibles" en el título de la pregunta? ¿Algún análisis más de un problema?
Lo que declaras se llama constante tipada . Y en este caso específico es una constante de matriz . La documentación dice (el énfasis es mío):
Para declarar una constante de matriz, encierre los valores de los elementos de la matriz, separados por comas, entre paréntesis al final de la declaración. Estos valores deben estar representados por expresiones constantes .
El código al que el compilador se opone es donde intenta utilizar una constante tipada donde solo se permite una expresión constante.
Esta es una de las áreas más frustrantes del lenguaje Delphi porque el lenguaje te obliga a repetirte.
Parece que esto no es posible, la causa subyacente es que ZeroRec no es realmente una constante, sino que se parece más a una variable estática inicializada.
Si se especifica {$ WRITEABLECONST ON} , puede cambiarse trivialmente. Incluso con $ WRITEABLECONST desactivado, se puede cambiar mediante algún tipo de conversión de creatividad (probado en XE2):
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
MyRecord = record MyField: Integer end;
PMyRecord = ^MyRecord;
const
Typical: array[0..1] of MyRecord = ((MyField: 0), (MyField: 1));
{ now I tried to achieve more clarity by declaring a specific constant }
ZeroRec: MyRecord = (MyField: 0);
{ and compiler refused to accept that }
// Bad: array[0..1] of MyRecord = ((MyField: Zero), (MyField: 1)); { E2029 ''('' expected but identifier ''Zero'' found }
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
WriteLn(ZeroRec.MyField);
PMyRecord(@ZeroRec)^.MyField := 2;
WriteLn(ZeroRec.MyField);
readln;
except
on E: Exception do
Writeln(E.ClassName, '': '', E.Message);
end;
end.
Esto producirá
0
2
El comportamiento también es evidente con tipos simples,
Zero = 0;
ZeroRec: MyRecord = (MyField: Zero);
compila como se esperaba, sin embargo
Zero : Integer = 0;
ZeroRec: MyRecord = (MyField: Zero);
da [DCC Error] Project3.dpr (19): E2026 Se espera la expresión constante