سؤال

حديثاً، لي بالدوين أظهر كيفية كتابة أ وظيفة حفظ الوسيطة العامة والمتغيرة.اعتقدت أنه سيكون من الأفضل إرجاع دالة أبسط تتطلب معلمة واحدة فقط.إليكم محاولتي الزائفة الكاملة:

local function memoize(f)
   local cache = {}

   if select('#', ...) == 1 then
      return function (x)
                if cache[x] then
                   return cache[x]
                else
                   local y = f(x)
                   cache[x] = y
                   return y
                end
              end
   else
      return function (...)
                local al = varg_tostring(...)
                if cache[al] then
                   return cache[al]
                else
                   local y = f(...)
                   cache[al] = y
                   return y
                end
             end
   end
end

بوضوح، select('#', ...) يفشل في هذا السياق ولن أفعل ما أريده حقًا على أي حال.هل هناك أي طريقة لمعرفة الداخل حفظ كم عدد الحجج F تتوقع؟


"لا" هي إجابة جيدة إذا كنت تعرف ذلك بالتأكيد.ليس مشكلة كبيرة استخدام اثنين منفصلين حفظ المهام.

هل كانت مفيدة؟

المحلول

أعتقد أنه يمكنك الدخول إلى معلومات التصحيح وتحديد ذلك من الكود المصدري، ولكن في الأساس "لا"، آسف.

نصائح أخرى

نعم، لوظائف Lua ولكن ليس لوظائف C.انها معذبة بعض الشيء وسطحية قليلا.

debug.getlocal يعمل على وظائف تسمى لذا عليك استدعاء الوظيفة المعنية.ولا يظهر أي تلميح لذلك ... ما لم تمر المكالمة بمعلمات كافية.الكود أدناه يحاول 20 معلمة.

debug.sethook مع حدث "call" يعطي فرصة لاعتراض الوظيفة قبل تشغيل أي رمز.

تعمل هذه الخوارزمية مع Lua 5.2.الإصدارات الأقدم ستكون متشابهة ولكنها ليست هي نفسها:

assert(_VERSION=="Lua 5.2", "Must be compatible with Lua 5.2")

مكرر مساعد صغير (يمكن تضمينه لتحقيق الكفاءة):

local function getlocals(l)
  local i = 0
  local direction = 1
  return function ()
    i = i + direction
    local k,v = debug.getlocal(l,i)
    if (direction == 1 and (k == nil or k.sub(k,1,1) == '(')) then 
      i = -1 
      direction = -1 
      k,v = debug.getlocal(l,i) 
    end
    return k,v
  end
end

إرجاع التوقيع (ولكن يمكن إرجاع عدد المعلمات واستخداماتVarargs بدلاً من ذلك):

local function dumpsig(f)
  assert(type(f) == 'function', 
    "bad argument #1 to 'dumpsig' (function expected)")
  local p = {}
  pcall (function() 
    local oldhook
    local hook = function(event, line)
      for k,v in getlocals(3) do 
        if k == "(*vararg)" then 
          table.insert(p,"...") 
          break
        end 
        table.insert(p,k) end
      debug.sethook(oldhook)
      error('aborting the call')
    end
    oldhook = debug.sethook(hook, "c")
    -- To test for vararg must pass a least one vararg parameter
    f(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
  end)
  return "function("..table.concat(p,",")..")"  
end

أنا متأكد من أنك لا تستطيع أن تفعل ذلك في لوا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top