الإكراه والتحويل بين الأنواع
تعلّم الإكراه التلقائي بين السلاسل النصية والأرقام، والتحويل الصريح باستخدام tonumber وtostring
الإكراه والتحويل بين الأنواع درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Lua Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Lua Academy 4 دروس في المجموع.
ما التحويل القسري للأنواع؟
التحويل القسري للأنواع هو التحويل التلقائي لقيمة من نوع إلى آخر عندما يتطلب السياق ذلك. تُجري Lua التحويل القسري في اتجاهين محددين: من سلسلة نصية إلى عدد في السياقات الحسابية، ومن عدد إلى سلسلة نصية في سياقات الدمج.
وعلى خلاف JavaScript، فإن التحويل القسري في Lua محدود ويمكن التنبؤ به. فهي لا تحوّل القيم المنطقية إلى أعداد أو الجداول إلى سلاسل نصية تلقائيًا.
-- String to number (arithmetic context)
print("10" + 5) -- 15 (coerced)
print("3.14" * 2) -- 6.28
-- Number to string (concatenation context)
print(10 .. "px") -- 10px
print(3.14 .. "!") -- 3.14!
-- No boolean coercion
-- print(true + 1) -- ERROR!قواعد التحويل القسري من سلسلة نصية إلى عدد
عندما تظهر سلسلة نصية في تعبير حسابي، تحاول Lua تحويلها إلى عدد. وإذا لم تمثل السلسلة عددًا صالحًا، يحدث خطأ وقت التشغيل. تشمل السلاسل العددية الصالحة الأعداد الصحيحة ("42")، والأعداد العشرية ("3.14")، والأعداد السداسية عشرية ("0xff")، والصيغة العلمية ("1e3").
تُقبل السلاسل التي تحتوي على مسافات بيضاء في بدايتها أو نهايتها؛ إذ تزيلها Lua أثناء التحويل القسري.
print("42" + 0) -- 42 (integer)
print("3.14" + 0) -- 3.14 (float)
print("0xff" + 0) -- 255 (hex)
print(" 10 " + 0) -- 10 (whitespace ok)
print("1e3" + 0) -- 1000.0
-- This will error:
-- print("hello" + 0) -- attempt to perform arithmetic on a string valueالتحويل القسري من عدد إلى سلسلة نصية
عند دمج عدد باستخدام ..، تحوّله Lua تلقائيًا إلى سلسلة نصية. وتتحول الأعداد الصحيحة إلى تمثيلها العشري، بينما قد تكتسب الأعداد العشرية منازل عشرية. وللتحكم الدقيق في التنسيق، استخدم دائمًا tostring() أو string.format() بدلًا من الاعتماد على التحويل القسري الضمني.
print(10 .. "!") -- 10!
print(3.14 .. "!") -- 3.14!
print(1/3 .. "!") -- 0.33333333333333!
-- Explicit is better for precision
print(string.format("%.2f", 1/3)) -- 0.33
print(tostring(10)) -- 10
print(tostring(10.0)) -- 10.0tonumber(): التحويل الصريح
تحوّل tonumber(v) قيمةً صراحةً إلى عدد. وتُرجع العدد المحوّل عند النجاح، أو nil إذا فشل التحويل؛ ولا تُطلق خطأً مطلقًا. ويمكن تحديد أساس اختياري (من 2 إلى 36) لتحليل الأعداد الصحيحة، ما يتيح التحويل من النظام الثنائي والثماني والسداسي عشري.
تحقّق دائمًا من أن القيمة التي تُرجعها tonumber() ليست nil عند معالجة إدخال المستخدم.
print(tonumber("42")) -- 42
print(tonumber("3.14")) -- 3.14
print(tonumber("0xFF")) -- 255
print(tonumber("hello")) -- nil (no error!)
print(tonumber(true)) -- nil
-- Base conversion
print(tonumber("ff", 16)) -- 255
print(tonumber("11", 2)) -- 3 (binary)
print(tonumber("77", 8)) -- 63 (octal)tostring(): التحويل الصريح
تحوّل tostring(v) أي قيمة إلى سلسلة نصية. وبالنسبة إلى الأعداد، تُنتج سلسلة بالصيغة العشرية أو العلمية. وبالنسبة إلى القيم المنطقية، تُنتج "true" أو "false". وبالنسبة إلى nil، تُرجع "nil". أما الجداول والدوال، فتُرجع عنوانًا مثل "table: 0x..." ما لم تُعرَّف دالة metamethod باسم __tostring.
print(tostring(42)) -- 42
print(tostring(3.14)) -- 3.14
print(tostring(true)) -- true
print(tostring(false)) -- false
print(tostring(nil)) -- nil
print(tostring({})) -- table: 0x...
-- Useful for safe concatenation
local val = nil
local msg = "Value: " .. tostring(val)
print(msg) -- Value: nilmath.tointeger()
تحوّل math.tointeger(x) (في Lua 5.3 فأحدث) عددًا عشريًا إلى عدد صحيح فقط إذا كانت قيمة العدد تمثل عددًا صحيحًا بدقة. وإذا كان التحويل سيفقد الدقة، تُرجع nil. وهذا أكثر أمانًا من math.floor() التي تنجح دائمًا، لكنها قد تقتطع الجزء العشري بصمت.
استخدم هذه الدالة عندما تحتاج إلى التحقق الصارم من صحة العدد الصحيح، مثلًا عند التعامل مع واجهات برمجية تتطلب أعدادًا صحيحة دقيقة.
print(math.tointeger(5.0)) -- 5 (exact)
print(math.tointeger(5.5)) -- nil (not exact)
print(math.tointeger(2^53)) -- 9007199254740992
-- Contrast with math.floor
print(math.floor(5.9)) -- 5 (truncates)
print(math.floor(5.0)) -- 5
-- Check before use
local n = math.tointeger(val) or error("need integer")التحويل القسري في المقارنات
لا تُجري Lua تحويلًا قسريًا للأنواع عند مقارنات التساوي. فالتعبير 1 == "1" يُرجع دائمًا false لأن المعاملين من نوعين مختلفين. أما العوامل العلاقية (< و> وغيرهما) فتُفعّل التحويل القسري بين السلاسل النصية والأعداد، ولكن فقط عندما يكون المعاملان من النوع نفسه. ويؤدي خلط الأنواع في مقارنات الترتيب إلى حدوث خطأ.
print(1 == "1") -- false (no coercion)
print(1 == 1.0) -- true (int/float equal)
-- Ordering: same type only
print("abc" < "abd") -- true (string compare)
print(1 < 2) -- true (number compare)
-- This ERRORS: mixing string and number
-- print(1 < "2") -- attempt to compare number with stringتطبيق عملي: تحليل إدخال المستخدم
من الأنماط الشائعة جدًا في برامج Lua قراءة سلسلة نصية من إدخال المستخدم (مثلًا عبر io.read()) وتحويلها إلى عدد. استخدم دائمًا tonumber() وتحقّق من أن القيمة ليست nil لمعالجة الإدخال غير الصالح بسلاسة بدلًا من تعطل البرنامج.
-- Safe input parsing pattern
local function parseNumber(input)
local n = tonumber(input)
if n == nil then
return nil, "Invalid number: " .. tostring(input)
end
return n, nil
end
local val, err = parseNumber("42")
print(val, err) -- 42 nil
local val2, err2 = parseNumber("abc")
print(val2, err2) -- nil Invalid number: abcمشكلات دقة الأعداد الصحيحة والعشرية
تتمتع الأعداد العشرية بدقة محدودة. وقد تنتج عن العمليات التي تخلط بين العدد الصحيح والعدد العشري نتائج غير متوقعة بسبب تمثيل IEEE 754. أكبر عدد صحيح يمكن تمثيله بدقة على هيئة عدد عشري مزدوج هو 2^53 = 9,007,199,254,740,992. وتفقد الأعداد الصحيحة الأكبر من ذلك دقتها عند تخزينها كأعداد عشرية.
في Lua 5.3 فأحدث، تدعم الأعداد الصحيحة الأصلية ذات 64 بت قيمًا دقيقة حتى 2^63-1، وهي أكبر بكثير. استخدم دائمًا العمليات الحسابية على الأعداد الصحيحة عندما تكون الدقة مهمة.
-- Float precision limit
print(2^53) -- 9.007...e+15
print(2^53 + 1 == 2^53) -- true (precision lost!)
-- Integer stays exact
local big = math.maxinteger
print(big) -- 9223372036854775807
print(math.type(big)) -- integer
-- Mixing promotes to float
print(math.type(1 + 1.0)) -- floatتحويلات تنسيق السلاسل النصية
تُعد string.format() الأداة الأقوى لتحويل الأعداد إلى سلاسل نصية عندما تحتاج إلى التحكم في الدقة والحشو والصيغة. وهي تتبع محددات تنسيق printf في لغة C. استخدمها للعرض، وكتابة الملفات، وكل موضع لا يكون فيه التمثيل الافتراضي لـtostring() كافيًا.
print(string.format("%d", 255)) -- 255
print(string.format("%x", 255)) -- ff
print(string.format("%05d", 42)) -- 00042
print(string.format("%.2f", 3.14159)) -- 3.14
print(string.format("%e", 12345.0)) -- 1.234500e+04
print(string.format("%s=%d", "x", 10)) -- x=10تحقّق سريع
ماذا تُرجع tonumber("hello") في Lua؟
مراجعة: التحويل القسري والتحويل الصريح للأنواع
ما تعلّمته:
- تحوّل Lua السلاسل النصية تلقائيًا إلى أعداد في العمليات الحسابية، والأعداد إلى سلاسل نصية عند الدمج
- تُرجع
tonumber()القيمة nil عند الفشل — تحقّق منها دائمًا! - تحوّل
tostring()أي قيمة بأمان إلى سلسلة نصية - لا تُجري المقارنة (
==) أي تحويل قسري؛ فالأنواع المختلفة لا تكون متساوية أبدًا - استخدم
string.format()لتنسيق الأعداد بدقة - حد دقة الأعداد العشرية هو 2^53؛ استخدم الأعداد الصحيحة الأصلية للقيم الكبيرة الدقيقة
التالي: تدفق التحكم باستخدام if/elseif/else والحلقات.
الأسئلة الشائعة
هل درس «الإكراه والتحويل بين الأنواع» مجاني؟
نعم — نص درس «الإكراه والتحويل بين الأنواع» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.
ماذا ستتعلم في «الإكراه والتحويل بين الأنواع»؟
تعلّم الإكراه التلقائي بين السلاسل النصية والأرقام، والتحويل الصريح باستخدام tonumber وtostring تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟
لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «الإكراه والتحويل بين الأنواع»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟
نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- نظرة عامة على أنواع بيانات Lua
- تعريف المتغيرات في Lua
- المعاملات الحسابية والعلاقية
- الإكراه والتحويل بين الأنواع