دلفي: جميع الثوابت ثابتة ، لكن بعضها أكثر ثباتًا من غيرها؟
-
01-10-2019 - |
سؤال
انصح:
const
clHotlight: TColor = $00FF9933;
clLink = clHotLight; //alias of clHotlight
[Error] file.pas: Constant expression expected
والصياغة البديلة التي تعمل:
const
clHotlight = TColor($00FF9933);
clLink = clHotLight; //alias of clHotlight
يشرح.
ثم فكر في:
const
AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID
[Error] file.pas: Constant expression expected
وإصلاح.
يحرر: الكلمة الرئيسية المضافة const
قبل الإعلانات لم يصدق شخص ما أنهم كانوا.
المحلول
clHotlight: TColor = $00FF9933;
ليس ثابتًا ولكن ثابت مطبوع (= متغير ثابت) ، أي أن برنامج التحويل البرمجي يحتفظ بفتحة في الذاكرة لـ tcolor التي ستحتفظ بالقيمة $00FF9933
في البداية في وقت التشغيل.
نظرًا لأنه يمكن تغيير هذه القيمة لاحقًا (مع خيار const القابل للتخصيص) ، فهي ليست ثابتة حقيقية ولا يمكن قبولها من قبل المترجم clLink = clHotLight;
clHotlight = TColor($00FF9933);
هو نفسه تماما مثل clHotlight = $00FF9933;
إنه ثابت حقيقي وسيحل محل التحويل البرمجي clHotlight
حسب قيمتها $00FF9933
أينما يظهر في الكود. ولل clLink
كذلك.
اقرأ هذا السؤال (في Delphi 7 ، لماذا يمكنني تعيين قيمة إلى const؟) وكل الإجابات الجيدة هناك ...
تحرير: حول tguid ...
المشكلة هي تلك الكتابة AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
ليس مناسبا.
إنه يستخدم بعض سحر المترجم للإتصال StringToGUID
خلف المشهد ، مما يسمح للراحة بالتعبير عن GUID كسلسلة ليست بطبيعتها. هم سجلات.
لذلك ، المحاولة AdministratorGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
لن يعمل. هذا ليس جديدا ...
الحل البديل هو أن يكون ثابت مطبوع و المتغيرات مشيرا إلى نفس منطقة الذاكرة باستخدام absolute
التوجيه:
const
AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
var
SuperuserGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
RootGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
نصائح أخرى
جربت هذا الرمز:
const
CAnswer1 = 42;
CAnswer2 : Integer = 42;
var
LAnswer : Integer;
begin
LAnswer := CAnswer1;
LAnswer := CAnswer2;
end;
وهنا الكود المنتجة:
Project9.dpr.18: LAnswer := CAnswer1;
004101AC C7056C6E41002A00 mov [$00416e6c],$0000002a //<- assign a hard-coded "42" value
Project9.dpr.19: LAnswer := CAnswer2;
004101B6 A1701C4100 mov eax,[$00411c70] //<- fetch a variable's content
004101BB A36C6E4100 mov [$00416e6c],eax //<- assign this content
أنت على حق: بعض الثوابت أكثر ثباتًا من غيرها. يتم التعامل مع الثابت الثاني في الواقع من قبل المترجم كمتغير.
clHotlight: TColor = $00FF9933;
^
يعلن clHotlight
ك 'عامل"(حسنًا ، حسنًا ،" ثابت قابل للتخصيص "إذا سمحت بذلك في خيارات البرمجيات) عن طريق :
.
كما وجدت ، أعلن:
clHotlight = TColor($00FF9933);
لا يوجد تخصيص من clHotlight
حتى يتم تحديده لاحقًا.
الأمر نفسه ينطبق على GUID الخاص بك.
تنشأ المشكلة لأن الثابت المكتوب ليس ثابتًا حقًا ، كما تم شرحه بدرجات متفاوتة من الوضوح والنجاح من قبل الآخرين.
ما لم يظهر حتى الآن هو كيفية العمل حول المشكلة (في عدد كبير من الحالات) ، على الرغم من أن الزوجين اقتربان من التخلي عن هذا السر ... :)
في حالتك المحددة ، يمكنك الالتفاف على المشكلة من خلال عكس "التعرج" من القيمة والإعلان الثابت المكتوبة على النحو التالي:
const
clLink = $00FF9933;
clHotlight: TColor = clLink;
كلانك يوفر الآن ثابتك الحقيقي و Clhotlight هو الثابت المكتوب الذي له نفس القيمة كلانك.
بالنسبة إلى GUID ، يمكن استخدام نفس التقنية ، ولكن عليك أن تضع في اعتبارك التعبير الثابت الطبيعي المستخدم لتهيئة ثابت GUID - لا يستخدم سجلًا ولكن سلسلة حرفية بسيطة ، لذلك:
const
ID_CONSTANT = '{AA1C8AF2-C290-40AB-9CF5-2888A46E1660}';
GUID_CONSTANT: TGUID = ID_CONSTANT;
ملاحظة: هذه ثوابت GUID قابلة للاستخدام تمامًا في جميع الأماكن التي يكون فيها tguidمطلوب ، على سبيل المثال isequalguid(tguid ، guid_constant) وما إلى ذلك
قرأت هنا فهم الثوابت المكتوبة في دلفي
يجب أن يكون الجانب الأيمن للإعلان الثابت "تعبيرًا ثابتًا" ، والذي يُعرّف بأنه "تعبير ثابت هو تعبير يمكن للمترجم تقييمه دون تنفيذ البرنامج الذي يحدث فيه". يمكنك العثور على بناء الجملة المقبول بالكامل للتعبير المستمر في دليل اللغة. لاحظ أن دليل اللغة ينص صراحة على أن "الثوابت المكتوبة لا يمكن أن تحدث في تعبيرات ثابتة". - وهذا هو السبب في فشل إعلاناتك ، كلا clhotlight: tcolor = $ 00FF9933 ؛ و AdministratorGuid: tguid = ... ؛ تكتب الثوابت. أيضًا ، لا يمكن أن يتضمن التعبير المستمر مكالمات الوظائف باستثناء تلك المذكورة في دليل اللغة (IE Length () ، SizeOF () ، وبعضها الآخر) الذي يمكن للمترجم بحسابه في وقت الترجمة. أعد كتابة بهذه الطريقة:
const
AdminGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
AdministratorGUID: TGUID = AdminGUID;
SuperuserGUID: TGUID = AdminGUID;
وسوف تعمل.
مرحبًا بك في Delphi Evolution. في Delphi 1 و 2 ، لا يمكنك تعيين قيمة ثابتة أولية إلى Var Global (على سبيل المثال: var xvar: integer = 1). الطريقة الوحيدة التي يمكنك من خلالها القيام بذلك هي استخدام const xvar: integer = 1) وبعضها في الرموز في الرموز ، يمكنك بعد ذلك تغييره إلى شيء ما إذا رغبت في ذلك. حتى يتخلصوا من هذه الميزة القديمة ، لا يمكنك استخدام "Const XVAR: Integer" كقيمة const.
هتاف فام