0Pricing
Lua Academy · درس

المعامل ... والمعاملات المتغيرة العدد

تعامل مع قوائم المعاملات متغيرة الطول باستخدام ... وselect()

المعامل ... والمعاملات المتغيرة العدد درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Lua Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Lua Academy 4 دروس في المجموع.

الوسائط المتغيرة

يمكن لدالة Lua قبول عدد متغير من الوسائط باستخدام ... (ثلاث نقاط) في قائمة المعاملات. وتمثل ... داخل الدالة الوسائط الإضافية. ويمكنك استخدامها في التعبيرات، أو تمريرها إلى دوال أخرى، أو تحويلها إلى جدول.

local function sum(...)
  local total = 0
  for _, v in ipairs({...}) do
    total = total + v
  end
  return total
end

print(sum(1, 2, 3))        -- 6
print(sum(10, 20, 30, 40)) -- 100

استخدام select() مع الوسائط المتغيرة

تُرجع select(n, ...) الوسائط بدءًا من الموضع n. وتُرجع select("#", ...) العدد الإجمالي للوسائط، بما في ذلك قيم nil. وهذا أكثر أمانًا من #{...} الذي يتوقف عند أول فجوة nil.

local function inspect(...)
  local n = select("#", ...)
  print("count:", n)
  for i = 1, n do
    print(i, select(i, ...))
  end
end

inspect("a", "b", nil, "d")
-- count: 4
-- 1  a
-- 2  b
-- 3  nil
-- 4  d

تمرير ... إلى دالة أخرى

يمكنك تمرير الوسائط المتغيرة مباشرةً إلى دالة أخرى باستخدام f(...). وعندما تظهر ... بوصفها الوسيط الأخير في الاستدعاء، تُمرر جميع الوسائط المتغيرة. ويفيد ذلك في تغليف الدوال أو تسجيل الأحداث.

local function log(level, ...)
  io.write("[" .. level .. "] ")
  print(...)
end

log("INFO", "Server started on port", 8080)
log("ERROR", "File not found:", "config.lua")
-- [INFO] Server started on port  8080
-- [ERROR] File not found:  config.lua

table.pack وtable.unpack

حوّل الوسائط المتغيرة إلى جدول باستخدام table.pack(...)، التي تخزن العدد أيضًا في الحقل n. وحوّل الجدول مرة أخرى إلى وسائط متغيرة باستخدام table.unpack(t, i, j). وتمنحك الدالتان معًا تحكمًا كاملًا في قوائم الوسائط المتغيرة.

local function pack_and_show(...)
  local packed = table.pack(...)
  print("n =", packed.n)
  for i = 1, packed.n do
    print(i, packed[i])
  end
end

pack_and_show(10, nil, 30)
-- n = 3
-- 1  10
-- 2  nil
-- 3  30

الوسائط الثابتة والمتغيرة معًا

يمكن أن تحتوي الدالة على معاملات ثابتة ومتغيرة معًا. تأتي المعاملات الثابتة أولًا، ثم تلتقط ... بقية الوسائط. وتُسنَد المعاملات الثابتة قبل وضع البقية في ....

local function printf(fmt, ...)
  io.write(string.format(fmt, ...))
end

printf("Hello, %s! You are %d years old.\n", "Alice", 30)
printf("Pi is approximately %.4f\n", math.pi)

local function firstAndRest(first, ...)
  print("first:", first)
  print("rest count:", select("#", ...))
end
firstAndRest(1, 2, 3, 4)

الوسائط المتغيرة في مُنشئ جدول

يمكنك نشر الوسائط المتغيرة مباشرةً داخل مُنشئ جدول: {...}. وعند استخدامها بوصفها العنصر الأخير، تُدرج جميع الوسائط. لكن فجوات nil قد تربك # — لذلك يُفضَّل استخدام table.pack عند الحاجة إلى أعداد دقيقة.

local function toArray(...)
  return {...}  -- collect all args as array
end

local arr = toArray("x", "y", "z")
for i, v in ipairs(arr) do
  print(i, v)
end
-- 1  x
-- 2  y
-- 3  z

تعبيرات الوسائط المتغيرة

يمكن أن تظهر ... في أي موضع من مواضع التعبير. ففي الإسناد المتعدد، تتمدد إلى جميع قيمها. أما في التعبير الحسابي، فلا تُستخدم إلا القيمة الأولى. ويساعد فهم هذا السلوك على تجنب الأخطاء الدقيقة عند مزج ... بتعبيرات أخرى.

local function first(...)
  local x = ...
  return x
end

print(first(10, 20, 30))  -- 10  (only first)

local function addFirst(n, ...)
  local x = ...
  return n + x
end
print(addFirst(5, 3, 99)) -- 8  (3 is first ...)

تستخدم print() الوسائط المتغيرة

إن print() المضمّنة في Lua هي نفسها دالة ذات وسائط متغيرة. فهي تقبل أي عدد من الوسائط، وتحول كل واحدة منها إلى سلسلة نصية، وتفصل بينها بعلامات تبويب. ويساعدك فهم ذلك على كتابة دوال أدوات مشابهة.

-- print is vararg
print(1, 2, 3)           -- 1  2  3
print("a", nil, "b")     -- a  nil  b
print()                  -- (empty line)

-- Reimplementing a simple print-like function
local function myprint(...)
  local parts = {}
  for i = 1, select("#", ...) do
    parts[i] = tostring(select(i, ...))
  end
  io.write(table.concat(parts, "\t") .. "\n")
end
myprint(10, nil, 30)

التمرير مع pcall

ادمج pcall مع الوسائط المتغيرة لإنشاء غلاف عام للاستدعاء الآمن. يقبل الغلاف دالة وأي عدد من الوسائط، ويستدعيها عبر pcall، ثم يُرجع النتائج أو خطأً.

local function safeCall(fn, ...)
  local ok, result = pcall(fn, ...)
  if ok then
    return result
  else
    print("Error:", result)
    return nil
  end
end

local function divide(a, b)
  assert(b ~= 0, "division by zero")
  return a / b
end

print(safeCall(divide, 10, 2))   -- 5.0
print(safeCall(divide, 10, 0))  -- Error: ...

نمط تجميع الوسائط المتغيرة

من الأنماط الشائعة للوسائط المتغيرة التكرار على جميع الوسائط وتجميع نتيجة. ويمكن تنفيذ ذلك باستخدام جدول محلي أو بجمع القيم مباشرةً عبر select. وكلا الأسلوبين صحيح، لكن أسلوب الجدول أوضح عند التعامل مع عدد كبير من الوسائط.

local function average(...)
  local n = select("#", ...)
  if n == 0 then return 0 end
  local total = 0
  for i = 1, n do
    total = total + select(i, ...)
  end
  return total / n
end

print(average(10, 20, 30, 40))  -- 25.0
print(average(5))               -- 5.0

تحقق سريع

ماذا تُرجع select("#", 1, nil, 3)؟

مراجعة: الوسائط المتغيرة

الملخص:

  • function f(...) — تقبل وسائط متغيرة
  • select("#", ...) — تحسب العدد بأمان، بما في ذلك قيم nil
  • select(n, ...) — تُرجع القيم بدءًا من الموضع n
  • table.pack(...) — تحول الوسائط المتغيرة إلى جدول مع العدد في .n
  • table.unpack(t) — تحول الجدول إلى وسائط متغيرة
  • تتمدد ... بالكامل في الموضع الأخير، أما في الموضع الأوسط فتعطي قيمة واحدة

الأسئلة الشائعة

هل درس «المعامل ... والمعاملات المتغيرة العدد» مجاني؟

نعم — نص درس «المعامل ... والمعاملات المتغيرة العدد» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.

ماذا ستتعلم في «المعامل ... والمعاملات المتغيرة العدد»؟

تعامل مع قوائم المعاملات متغيرة الطول باستخدام ... وselect() تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟

لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «المعامل ... والمعاملات المتغيرة العدد»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟

نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تعريف الدوال واستدعاؤها
  2. القيم المرجعة المتعددة
  3. المعامل ... والمعاملات المتغيرة العدد
  4. الاستدعاء الذاتي في Lua
← العودة إلى Lua Academy