खोज…


वाक्य - विन्यास

  • funcname = समारोह (Parama, paramB, ...) शरीर; वापसी एक विस्तृत समारोह - समाप्ति का अंत
  • समारोह funcname (Parama, paramB, ...) शरीर; वापसी की समाप्ति की तारीख - ऊपर के लिए आशुलिपि
  • स्थानीय funcname = समारोह (Parama, paramB, ...) शरीर; वापसी विस्तारक अंत - एक लंबोदर
  • स्थानीय कवकनाम ; funcname = समारोह (Parama, paramB, ...) शरीर; वापसी exprlist अंत - भेड़ का बच्चा है कि पुनरावर्ती कॉल कर सकते हैं
  • स्थानीय समारोह funcname (Parama, paramB, ...) शरीर; वापसी की समाप्ति की तारीख - ऊपर के लिए आशुलिपि
  • funcname (Parama, paramB, ...) - एक समारोह फोन
  • स्थानीय var = var या "डिफ़ॉल्ट" - एक डिफ़ॉल्ट पैरामीटर
  • वापसी शून्य, "त्रुटि संदेश" - एक त्रुटि के साथ गर्भपात करने का मानक तरीका

टिप्पणियों

फ़ंक्शन आमतौर पर function a(b,c) ... end साथ सेट होते हैं function a(b,c) ... end और शायद ही कभी एक अनाम फ़ंक्शन ( a = function(a,b) ... end ) के लिए एक चर सेट करने के साथ। मापदंडों के रूप में फ़ंक्शंस पास करते समय विपरीत सच है, अनाम फ़ंक्शंस का अधिकतर उपयोग किया जाता है, और सामान्य फ़ंक्शंस का उपयोग अक्सर नहीं किया जाता है।

एक कार्य को परिभाषित करना

function add(a, b)
    return a + b
end
-- creates a function called add, which returns the sum of it's two arguments

सिंटेक्स पर नजर डालते हैं। सबसे पहले, हम एक function कीवर्ड देखते हैं। खैर, यह बहुत वर्णनात्मक है। आगे हम add आइडेंटिफ़ायर देखते add ; नाम। फिर हम तर्क (a, b) देखते हैं कि ये कुछ भी हो सकते हैं, और ये स्थानीय हैं। केवल फ़ंक्शन बॉडी के अंदर ही हम उन्हें एक्सेस कर सकते हैं। चलो अंत तक छोड़ते हैं, हम देखते हैं ... ठीक है, end ! और यह सब बीच में फ़ंक्शन बॉडी है; कोड जिसे कॉल किया जाता है उसे चलाया जाता है। return कीवर्ड वह है जो फ़ंक्शन को वास्तव में कुछ उपयोगी आउटपुट देता है। इसके बिना, फ़ंक्शन कुछ भी नहीं लौटाता है, जो शून्य वापस करने के बराबर है। यह उन चीजों के लिए उपयोगी हो सकता है जो IO के साथ बातचीत करती हैं, उदाहरण के लिए:

function printHello(name)
    print("Hello, " .. name .. "!");
end 

उस फ़ंक्शन में, हमने रिटर्न स्टेटमेंट का उपयोग नहीं किया।

फ़ंक्शंस भी सशर्त रूप से मान लौटा सकते हैं, जिसका अर्थ है कि एक फ़ंक्शन में कुछ भी नहीं (एनआईएल) या एक मूल्य वापस करने का विकल्प होता है। यह निम्नलिखित उदाहरण में प्रदर्शित किया गया है।

function add(a, b)
    if (a + b <= 100) then
        return a + b -- Returns a value
    else
        print("This function doesn't return values over 100!") -- Returns nil
    end
end

एक फ़ंक्शन के लिए कॉमा द्वारा अलग किए गए कई मानों को वापस करना भी संभव है, जैसा कि दिखाया गया है:

function doOperations(a, b)
    return a+b, a-b, a*b
end

added, subbed, multiplied = doOperations(4,2)

कार्यों को स्थानीय भी घोषित किया जा सकता है

do
    local function add(a, b) return a+b end
    print(add(1,2)) --> prints 3
end
print(add(2, 2)) --> exits with error, because 'add' is not defined here

उन्हें तालिकाओं में भी बचाया जा सकता है:

tab = {function(a,b) return a+b end}
(tab[1])(1, 2) --> returns 3

एक समारोह बुला रहा है।

कार्य केवल तभी उपयोगी होते हैं जब हम उन्हें कॉल कर सकते हैं। फ़ंक्शन को कॉल करने के लिए निम्नलिखित सिंटैक्स का उपयोग किया जाता है:

print("Hello, World!")

हम print फ़ंक्शन को कॉल कर रहे हैं। "Hello, World" तर्क का उपयोग करना। जैसा कि स्पष्ट है, यह Hello, World को आउटपुट स्ट्रीम पर प्रिंट करेगा। लौटाया गया मूल्य सुलभ है, जैसे कोई अन्य चर होगा।

local added = add(10, 50) -- 60

एक फ़ंक्शन के मापदंडों में चर भी स्वीकार किए जाते हैं।

local a = 10
local b = 60

local c = add(a, b)

print(c)

एक मेज या एक स्ट्रिंग की अपेक्षा करने वाले कार्यों को एक स्वच्छ सिंटैक्टिक चीनी के साथ बुलाया जा सकता है: कॉल के आसपास के कोष्ठक को छोड़ा जा सकता है।

print"Hello, world!"
for k, v in pairs{"Hello, world!"} do print(k, v) end

अनाम कार्य

अनाम फ़ंक्शंस बनाना

अनाम फ़ंक्शंस नियमित Lua फ़ंक्शंस की तरह ही होते हैं, सिवाय इसके कि उनका कोई नाम नहीं है।

doThrice(function()
    print("Hello!")
end)

जैसा कि आप देख सकते हैं, फ़ंक्शन print या add जैसे किसी भी नाम को असाइन नहीं किया गया है। एक अनाम फ़ंक्शन बनाने के लिए, आपको केवल नाम छोड़ना होगा। ये कार्य तर्क भी ले सकते हैं।

सिंटैक्टिक शुगर को समझना

यह समझना महत्वपूर्ण है कि निम्नलिखित कोड

function double(x)
    return x * 2
end

वास्तव में सिर्फ एक आशुलिपि है

double = function(x)
    return x * 2
end

हालाँकि, उपरोक्त फ़ंक्शन अनाम नहीं है क्योंकि फ़ंक्शन सीधे एक चर को सौंपा गया है!

कार्य प्रथम श्रेणी के मान हैं

इसका मतलब है कि एक फ़ंक्शन समान अधिकारों के साथ एक मूल्य है जैसे कि संख्या और तार जैसे पारंपरिक मूल्य। फ़ंक्शंस को चर में, तालिकाओं में संग्रहीत किया जा सकता है, तर्क के रूप में पारित किया जा सकता है, और अन्य कार्यों द्वारा लौटाया जा सकता है।

इसे प्रदर्शित करने के लिए, हम एक "आधा" फ़ंक्शन भी बनाएंगे:

half = function(x)
    return x / 2
end

तो, अब हमारे पास दो चर, half और double , दोनों एक मान के रूप में एक फ़ंक्शन युक्त हैं। क्या होगा यदि हम एक फ़ंक्शन बनाना चाहते हैं जो दिए गए कार्यों में नंबर 4 को खिलाएगा, और दोनों परिणामों के योग की गणना करेगा?

हम इस फ़ंक्शन को sumOfTwoFunctions(double, half, 4) तरह कॉल करना चाहते हैं। यह double फ़ंक्शन, half फ़ंक्शन और पूर्णांक 4 को हमारे स्वयं के फ़ंक्शन में फीड करेगा।

function sumOfTwoFunctions(firstFunction, secondFunction, input)
    return firstFunction(input) + secondFunction(input)
end

उपरोक्त sumOfTwoFunctions फ़ंक्शन दर्शाता है कि कार्यों को तर्कों के भीतर कैसे पास किया जा सकता है, और किसी अन्य नाम से एक्सेस किया जा सकता है।

डिफ़ॉल्ट पैरामीटर

function sayHello(name)
    print("Hello, " .. name .. "!")
end

यह फ़ंक्शन एक साधारण फ़ंक्शन है, और यह अच्छी तरह से काम करता है। लेकिन क्या होगा यदि हम सिर्फ sayHello() ?

stdin:2: attempt to concatenate local 'name' (a nil value)
stack traceback:
    stdin:2: in function 'sayHello'
    stdin:1: in main chunk
    [C]: in ?

यह बिल्कुल महान नहीं है। इसे ठीक करने के दो तरीके हैं:

  1. आप तुरंत समारोह से लौटते हैं:

    function sayHello(name)
      if not (type(name) == "string") then
        return nil, "argument #1: expected string, got " .. type(name)
      end -- Bail out if there's no name.
      -- in lua it is a convention to return nil followed by an error message on error
    
      print("Hello, " .. name .. "!") -- Normal behavior if name exists.
    end
    
  2. आप एक डिफ़ॉल्ट पैरामीटर सेट करें।

    ऐसा करने के लिए, बस इस सरल अभिव्यक्ति का उपयोग करें

function sayHello(name)
    name = name or "Jack" -- Jack is the default, 
                          -- but if the parameter name is given, 
                          -- name will be used instead
    print("Hello, " .. name .. "!")
end

मुहावरा name = name or "Jack" काम करता है क्योंकि or लुआ शॉर्ट सर्किट में। एक की बाईं ओर आइटम हैं or के अलावा और कुछ है nil या false , तो दाईं ओर का मूल्यांकन कभी नहीं किया गया है। दूसरी ओर, यदि sayHello को कोई पैरामीटर नहीं कहा जाता है, तो name nil होगा, और इसलिए स्ट्रिंग "Jack" को name । (ध्यान दें कि यह मुहावरा काम नहीं करेगा, अगर प्रश्न में पैरामीटर के लिए बूलियन false उचित मूल्य है।)

एकाधिक परिणाम

Lua में कार्य कई परिणाम दे सकते हैं।

उदाहरण के लिए:

function triple(x)
    return x, x, x
end

किसी फ़ंक्शन को कॉल करते समय, इन मानों को सहेजने के लिए, आपको निम्न सिंटैक्स का उपयोग करना होगा:

local a, b, c = triple(5)

जिसके परिणामस्वरूप इस मामले में a = b = c = 5 होगा। चर की सूची में वांछित स्थान पर थ्रोअवे चर _ का उपयोग करके लौटाए गए मानों को अनदेखा करना भी संभव है:

local a, _, c = triple(5)

इस स्थिति में, दूसरा लौटाया गया मान अनदेखा कर दिया जाएगा। किसी भी वैरिएबल पर उन्हें न देकर वापसी मूल्यों को अनदेखा करना संभव है:

local a = triple(5)

चर a पहले वापसी मान आवंटित किया जाएगा और शेष दो को छोड़ दिया जाएगा।

जब परिणामों की एक परिवर्तनीय राशि किसी फ़ंक्शन द्वारा वापस की जाती है, तो कोई उन सभी को तालिका में संग्रहीत कर सकता है, इसके अंदर फ़ंक्शन निष्पादित करके:

local results = {triple(5)}

इस तरह, एक results तालिका पर पुनरावृति कर सकता है यह देखने के लिए कि फ़ंक्शन क्या लौटा।

ध्यान दें

यह कुछ मामलों में एक आश्चर्य हो सकता है, उदाहरण के लिए:

local t = {}
table.insert(t, string.gsub("  hi", "^%s*(.*)$", "%1")) --> bad argument #2 to 'insert' (number expected, got string)

ऐसा इसलिए होता है क्योंकि string.gsub 2 मान देता है: दिए गए स्ट्रिंग, प्रतिस्थापित पैटर्न की घटनाओं के साथ, और होने वाले मैचों की कुल संख्या।

इसे हल करने के लिए, या तो कॉल के चारों ओर एक मध्यवर्ती चर या पुट () का उपयोग करें, जैसे:

table.insert(t, (string.gsub("  hi", "^%s*(.*)$", "%1"))) --> works. t = {"hi"}

यह कॉल के पहले परिणाम को पकड़ लेता है, और बाकी को अनदेखा कर देता है।

विभिन्न प्रकार के तर्क

वैरेडिक तर्क

नामित तर्क

local function A(name, age, hobby)
    print(name .. "is " .. age .. " years old and likes " .. hobby)
end
A("john", "eating", 23) --> prints 'john is eating years old and likes 23'
-- oops, seems we got the order of the arguments wrong...
-- this happens a lot, specially with long functions that take a lot of arguments
-- and where the order doesn't follow any particular logic

local function B(tab)
    print(tab.name .. "is " .. tab.age .. " years old and likes " .. tab.hobby)
end
local john = {name="john", hobby="golf", age="over 9000", comment="plays too much golf"}
B(john)
--> will print 'John is over 9000 years old and likes golf'
-- I also added a 'comment' argument just to show that excess arguments are ignored by the function

B({name = "tim"}) -- can also be written as
B{name = "tim"} -- to avoid cluttering the code
--> both will print 'tim is nil years old and likes nil'
-- remember to check for missing arguments and deal with them

function C(tab)
    if not tab.age then return nil, "age not defined" end
    tab.hobby = tab.hobby or "nothing"
    -- print stuff
end

-- note that if we later decide to do a 'person' class
-- we just need to make sure that this class has the three fields
-- age, hobby and name, and it will be compatible with these functions

-- example:
local john = ClassPerson.new("John", 20, "golf") -- some sort of constructor
john.address = "some place" -- modify the object
john:do_something("information") -- call some function of the object
C(john) -- this works because objects are *usually* implemented as tables

तर्क प्रकारों की जाँच करना

कुछ कार्य केवल एक निश्चित प्रकार के तर्क पर काम करते हैं:

function foo(tab)
    return tab.bar
end
--> returns nil if tab has no field bar, which is acceptable
--> returns 'attempt to index a number value' if tab is, for example, 3
--> which is unacceptable

function kungfoo(tab)
    if type(tab) ~= "table" then
        return nil, "take your useless " .. type(tab) .." somewhere else!"
    end

    return tab.bar
end

इसके कई निहितार्थ हैं:

print(kungfoo(20)) --> prints 'nil, take your useless number somewhere else!'

if kungfoo(20) then print "good" else print "bad" end --> prints bad

foo = kungfoo(20) or "bar" --> sets foo to "bar"

अब हम जो भी पैरामीटर चाहते हैं उसके साथ फ़ंक्शन को कॉल कर सकते हैं, और यह प्रोग्राम को क्रैश नहीं करेगा।

-- if we actually WANT to abort execution on error, we can still do
result = assert(kungfoo({bar=20})) --> this will return 20
result = assert(kungfoo(20)) --> this will throw an error

तो, क्या होगा यदि हमारे पास एक फ़ंक्शन है जो किसी विशिष्ट वर्ग के उदाहरण के साथ कुछ करता है? यह मुश्किल है, क्योंकि कक्षाएं और ऑब्जेक्ट्स आमतौर पर टेबल होते हैं, इसलिए type फ़ंक्शन 'table' वापस आ जाएगा।

local Class = {data="important"}
local meta = {__index=Class}

function Class.new()
    return setmetatable({}, meta)
end
-- this is just a very basic implementation of an object class in lua

object = Class.new()
fake = {}

print(type(object)), print(type(fake)) --> prints 'table' twice

समाधान: मेटाटैबल्स की तुलना करें

-- continuation of previous code snippet
Class.is_instance(tab)
    return getmetatable(tab) == meta
end

Class.is_instance(object) --> returns true
Class.is_instance(fake) --> returns false
Class.is_instance(Class) --> returns false
Class.is_instance("a string") --> returns false, doesn't crash the program
Class.is_instance(nil) --> also returns false, doesn't crash either

बंद

do
    local tab = {1, 2, 3}
    function closure()
        for key, value in ipairs(tab) do
            print(key, "I can still see you")
        end
    end
    closure()
    --> 1 I can still see you
    --> 2 I can still see you
    --> 3 I can still see you
end

print(tab) --> nil
-- tab is out of scope

closure()
--> 1 I can still see you
--> 2 I can still see you
--> 3 I can still see you
-- the function can still see tab

विशिष्ट उपयोग उदाहरण

function new_adder(number)
    return function(input)
        return input + number
    end
end
add_3 = new_adder(3)
print(add_3(2)) --> prints 5

अधिक उन्नत उपयोग उदाहरण

function base64.newDecoder(str) -- Decoder factory
    if #str ~= 64 then return nil, "string must be 64 characters long!" end

    local tab = {}
    local counter = 0
    for c in str:gmatch"." do
        tab[string.byte(c)] = counter
        counter = counter + 1
    end

    return function(str)
        local result = ""

        for abcd in str:gmatch"..?.?.?" do
            local a, b, c, d = string.byte(abcd,1,-1)
            a, b, c, d = tab[a], tab[b] or 0, tab[c] or 0, tab[d] or 0
            result = result .. (
                string.char( ((a<<2)+(b>>4))%256 ) ..
                string.char( ((b<<4)+(c>>2))%256 ) ..
                string.char( ((c<<6)+d)%256 )
            )
        end
        return result
    end
end


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow