SajjadKhati
کاربر فعال <A href="http://forum.majidonline.com/f
نکاتی درباره توابع در لوا :
1) تابع با چندین مقدار بازگشتی :
یک تابع میتواند چندین مقدار بازگشتی را بازگرداند. در این صورت باید به تعداد مقدار بازگشتی آن تابع (مثلا فرض میکنیم تابع مان 3 مقدار بازگشتی دارد)، برایش متغییر تعریف کرد و همه ی متغییرها را با ویرگول از هم جدا کرد . مثلا در مثال زیر :
تابع بالا که اسمش func هست ، 3 مقدار Val1 و Val2 و Val3 را برمیگرداند . موقع فراخوانی ، هر کدام به ترتیب داخل متغییرهای مربوط به خودشان (که موقع فراخوانی تابع func از آن استفاده کردیم) ذخیره میشوند. یعنی مقدار بازگشتی Val1 (که در مثال بالا مقدارش 300 هست) داخل متغییر Plus و مقدار Val2 (که مقدارش 20000 هست) داخل متغییر multiplication و مقدار Val3 (که مقدارش 100 هست) داخل متغییر Minus ذخیره میشوند
یعنی اولین مقدار بازگشتی ، داخل الین متغییر و دومین مقدار بازگشتی داخل دومین متغییر و ... ذخیره شده است
توجه کنید که اگر مثلا در فراخوانی تابعی که 3 مقدار بازگشتی دارد ، فقط 2 متغییر به آن تابع اختصاص دهیم ، در واقع دو مقدار بازگشتی را فقط به آن تابع اختصاص دادیم و مقدار بازگشتی سوم ، بلا استفاده میماند . یا مثلا اگر این تابع را بدون اختصاص دادن متغییر فراخوانی کردیم ، فقط مقدار بازگشتی اول را برمیگرداند یعنی در مثال بالا اگر این طور بنویسیم:
تابع func ، فقط مقدار اول که Val1 بود (که مقدارش 300 میشد) را برمیگرداند
2) اجرای تابع داخل آرگومان:
اگر در تابعی ، تابع دیگری فراخوانی شود به عنوان آرگومان ، معلوم هست که اول تابع داخلی (تابعی که در آرگومان آن تابع فراخوانی شد) اجرا و مقدار بازگشتی اش (اگر داشت . در این مثالزیر ، مقدار بازگشتی اش ، عدد هست) به عنوان آرگومان تابعی که در آن فراخوانی شد ، ارسال میشود:
در مثال بالا ، اول تابعی که در آرگومان دوم تابع اولیه فراخوانی شد ، اجرا و مقدار بازگشتی اش به عنوان آرگومان دوم ، ارسال میشود
یا مثل مثال زیر :
3) اجرای تابع داخل تابع دیگر :
هر وقت تابعی داخل تابع دیگر باشد ، تابع داخلی آن ، مثل توابع دیگر تا از تابع خارجی آن فراخوانی نشود ، اجرا نمیشود . مثل :
در مثال بالا ، تا زمانی که تابع داخلی آن (تابع Sec) از تابع خارجی آن (تابع Init) فراخوانی نشود ، تابع Sec اجرا نمیشود .
باید توجه داشت که بصورت مستقیم نمیتوانیم تابع داخلی یک تابع را فراخوانی کنیم چون تابع اجرا نشده و تا تابعی اجرا نشود (و کلا هر مقداری در لوا تعریف نشود) ، مقدارش nil است یعنی در مثال بالا نمی توانیم این جوری فراخوانیکنیم :
4) بدست آوردن تعداد مقادیر بازگشتی یک تابع (select) :
برای درک تعداد مقادیر بازگشتی یک تابع ، میتوانید از تابع select (تابع اصلی لوا) کمک بگیرید
اولین آرگومان (ورودی) این تابع شماره ی متغییر (آرگومان) ای را میدهیم که در آرگومانهای بعدی این تابع نوشتیم . مثلا در مثال زیر :
چون در آرگومان اول ، عدد 2 آورده شد ، یعنی دومین آرگومان بعد از خودش (به غیر از خودش) را برگردان (یعنی سومین آرگومان) که میشود رشته ی word
در مثال زیر :
چون تابع func ، دو مقدار را برمیگرداند ، پس 2 مقدار در دو آرگومان تابع select ذخیره میشود (اولیین آرگومان تابع select که عدد 2 هست و دومین آرگومان که همان اولین مقدار بازگشتی تابع func (مقدار first) و سومین آرگومان هم برابر دومین مقدار بازگشتی تابع func (مقدار secand) است) پس معلوم است که خروجی تابع select ، یکی بعد از اولین آرگومان(که 2 است) یعنی سومین آرگومان تابع select که مقدار secand (که مقدارش 1 هست) میباشد
مثال بالا برابر است با مثال زیر :
اگر بجای اولین تابع select ، بجای شماره (عدد) ، رشته ی "#" را قرار دهیم ، تعداد آرگومان هایی که در آن وجود دارد را باز میگرداند . پس برای بدست آوردن تعداد مقادیر بازگشتی یک تابع ، کافیست در اولین آرگومان تابع select ، رشته ی "#" و در دومین آرگومانش ، تابع مورد نظر را فراخوانی کنیم . پس برای بدیت آوردن تعداد بازگشتی تابع func در مثال اول ، کافیست :
نکته : برای متوجه شدن تعداد مقادیر بازگشتی یک تابع ، از این روش استفاده میکنیم ولی برای متوجه شدن تعداد یک آرایه این تابع کارایی ندارد . برای این منظور کافیست علامت # (دقت کنید که این بار رشته نیست) را کنار اسم آرایه بگذارید (اما دقت کنید که این روش برای آرایه ها،در مواردی که عضو آرایه ها بصورت عدد نباشند (بصورت index نباشند) و با حروف تعریف شوند ، جواب نمیدهد که در این صورت باید از تابع Table.Count از AMS استفاده کنید وگرنه در لوا باید از تابع pairs در iterator ها (در مقاله های بعد ، آموزش ایتریتورها گفته خواهد شد) ، استفاده کنید)
5) استفاده از علامت آندرلاین _ برای متغییرهای بلا استفاده :
گاهی داخل بعضی از الگوریتم ها ، برای توابعی که چندین مقدار بازگشتی دارند ، از علامت آندرلاین _ برای آن متغییر استفاده میشود (یا با همان تابع select میتوان بهتر مدیریت کرد) . هر چند این متغییر هم مثل متغییرهای عادی قابل استفاده هست و فرقی ندارد که بجای آن ، از اسمی دیگر استفاده کرد :
که در اینجا متغییر اول تابع string.find ، که با _ مشخص شد ، استفاده نمیکنند (البته میشود استفاده هم کرد مثل بقیه ی متغییرها)
6) تابع با ورودی و آرگومان متفاوت :
برای تعریف تابع (و هر آرگومان دیگر) که تعداد آرگومان هایش از قبل مشخص نباشند ، از علامت سه تا نقطه ... استفاده میشود . بعد ورودی ها را داخل آرایه میریزیم و بعد با بدست آوردن تعداد آن (که با علامت # مشخص میشد) ، به الگوریتم مان میپردازیم :
7) تابع بی نام :
این نوع تابع که اسم ندارد ، اغلب زمانی به کار میاید که بعد از تعریف ، فورا اجرایش کنیم . البته به ندرت این نوع توابع رو در مثال ها میبینیم.
ساختارش هم مثل تابع معمولی است و فقط اسم ندارد به اضافه ی اینکه قبل تعریف تابع ، یک پرانتز باز میکنیم و بعد آن پرانتز را میبندیم و بلافاصله بعدش مثل اجرای همه ی توابع که نشانه ی شان (بعد از فراخوانی اسم تابع که آرگومان ها را مینویسیم) دو پرانتز است ، دو پرانتز را باز و میبندیم که نشانه ی اجرای تابع تعریف شده باشد .
ساختارش به شکل زیر است :
8) تبدیل رشته به تابع (loadstring) :
تابع loadstring که جزء توابع اصلی لواست ، رشته را به عنوان ورودی دریافت و به تابع قابل اجرا تبدیل میکند (البته اگر رشته ها طبق قواعد لوا یا AMS تعریف شده باشند)
چون مقدار بازگشتی اش تابع هست ، پس برای اجرای آن مثل همه ی توابع ، آخرش باید علامت تابع (که در نکته ی 7 گفته شد دو علامت پرانتز هست) گذاشته شود
نکته ی جالب توجه اینکه بعد از اجرای این تابع ، مقدار بازگشتی اش (مقدار بازگشتی loadstring بعد از اجرا) ، nil میشود
نکته ی بعد اینکه در لوا برای تعریف رشته هم از علامت " " و هم از علامت ' ' و هم از علامت [[ ]] استفاده میشود
در مثال زیر ، قبل از اجرا شدن تابع loadstring ، میتوانید نوع بازگشتی آنرا که تابع هست ، ببینید :
در مثال زیر هم (که با گذاشتن علامت دو پرانتز ، آخر تابع loadstring به منظور اجرای تابع بازگشتی آن) ، رشته ی اصلی را اجرا کنید و بعد ، نوع بازگشتی را که قبلا اجرا function یا تابع بود و بعد از اجرا که nil میشود را ببینید :
9) استفاده از حلقه در تابع :
اگر در تابعی ، حلقه ای بکار رود که داخل آن حلقه ، مقدار بازگشتی (return) برای تابع لحاظ شود ، آن تابع دیگر تکرار نمیشود با آنکه حلقه ی تکرار در آن وجود دارد مثل :
اما اگر مقدار بازگشتی خارج از آن حلقه تعریف شود ، موردی ندارد و تابع تکرار میشود مثل :
10) فراخوانی تابع با تک آرگومان آرایه ای :
اگر تابعی تعریف کنیم که فقط یک آرگومان آن هم از نوع آرایه داشته باشد (نه چندین آرگومان) ، میتوانیم علامت تابع یعنی پرانتز را هنگام فراخوانی نگذاریم یعنی :
11) ایجاد و فراخوانی آرایه به روشی دیگر :
اگر آرایه ای داشته باشیم که key (یا به اصطلاح سمت چپ تساوی آن ، در متغییری ذخیره شده باشد) ، مثل متغییر foo و x و y در آرایه ی زیر :
به 2 حالت میشود آنرا فراخوانی کرد که اول به این گونه:
برابر است با نوع دوم اش به این گونه :
برای ایجاد آرایه هم میشود key ها را بصورت در هم شماره بندی و مقدار دهی کرد یعنی :
که [1]t برابر رشته ی "word" و [3]t برابر 12 و [7]t برابر رشته ی "salam" و [10]t برابر 653 هست . توجه کنیم که در این حالت بقیه ی مقادیر nil هست مثل [2]t و ... و هم اینکه نباید در این حالت که همه ی key ها شماره گذاری شده اند ، بعضی از آنها را شماره گذاری نکنیم مثلا این طور صحیح نیست :
1) تابع با چندین مقدار بازگشتی :
یک تابع میتواند چندین مقدار بازگشتی را بازگرداند. در این صورت باید به تعداد مقدار بازگشتی آن تابع (مثلا فرض میکنیم تابع مان 3 مقدار بازگشتی دارد)، برایش متغییر تعریف کرد و همه ی متغییرها را با ویرگول از هم جدا کرد . مثلا در مثال زیر :
کد:
[FONT=tahoma]function func(a,b)[/FONT]
[FONT=tahoma]Val1 = a+b[/FONT]
[FONT=tahoma]Val2=a*b[/FONT]
[FONT=tahoma]Val3 = a-b[/FONT]
[FONT=tahoma]return Val1,Val2,Val3[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Plus,multiplication,Minus = func(200,100)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", "a+b = "..Plus.."\na*b = "..multiplication.."\na-b = "..Minus, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
تابع بالا که اسمش func هست ، 3 مقدار Val1 و Val2 و Val3 را برمیگرداند . موقع فراخوانی ، هر کدام به ترتیب داخل متغییرهای مربوط به خودشان (که موقع فراخوانی تابع func از آن استفاده کردیم) ذخیره میشوند. یعنی مقدار بازگشتی Val1 (که در مثال بالا مقدارش 300 هست) داخل متغییر Plus و مقدار Val2 (که مقدارش 20000 هست) داخل متغییر multiplication و مقدار Val3 (که مقدارش 100 هست) داخل متغییر Minus ذخیره میشوند
یعنی اولین مقدار بازگشتی ، داخل الین متغییر و دومین مقدار بازگشتی داخل دومین متغییر و ... ذخیره شده است
توجه کنید که اگر مثلا در فراخوانی تابعی که 3 مقدار بازگشتی دارد ، فقط 2 متغییر به آن تابع اختصاص دهیم ، در واقع دو مقدار بازگشتی را فقط به آن تابع اختصاص دادیم و مقدار بازگشتی سوم ، بلا استفاده میماند . یا مثلا اگر این تابع را بدون اختصاص دادن متغییر فراخوانی کردیم ، فقط مقدار بازگشتی اول را برمیگرداند یعنی در مثال بالا اگر این طور بنویسیم:
کد:
[FONT=tahoma]function func(a,b)[/FONT]
[FONT=tahoma]Val1 = a+b[/FONT]
[FONT=tahoma]Val2=a*b[/FONT]
[FONT=tahoma]Val3 = a-b[/FONT]
[FONT=tahoma]return Val1,Val2,Val3[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Dialog.Message("Notice", func(200,100), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
تابع func ، فقط مقدار اول که Val1 بود (که مقدارش 300 میشد) را برمیگرداند
2) اجرای تابع داخل آرگومان:
اگر در تابعی ، تابع دیگری فراخوانی شود به عنوان آرگومان ، معلوم هست که اول تابع داخلی (تابعی که در آرگومان آن تابع فراخوانی شد) اجرا و مقدار بازگشتی اش (اگر داشت . در این مثالزیر ، مقدار بازگشتی اش ، عدد هست) به عنوان آرگومان تابعی که در آن فراخوانی شد ، ارسال میشود:
کد:
[FONT=tahoma]Dialog.Message("Notice", Dialog.Message("Notice", "Your message here.", MB_YESNO, MB_ICONINFORMATION, MB_DEFBUTTON1), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
در مثال بالا ، اول تابعی که در آرگومان دوم تابع اولیه فراخوانی شد ، اجرا و مقدار بازگشتی اش به عنوان آرگومان دوم ، ارسال میشود
یا مثل مثال زیر :
کد:
[FONT=tahoma]function first(arg1)[/FONT]
[FONT=tahoma]arg1=arg1^2[/FONT]
[FONT=tahoma]return arg1[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]function secand(arg2,arg3)[/FONT]
[FONT=tahoma]new=arg2/arg3[/FONT]
[FONT=tahoma]return new[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]NewNum = secand(first(6),9)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", NewNum, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
3) اجرای تابع داخل تابع دیگر :
هر وقت تابعی داخل تابع دیگر باشد ، تابع داخلی آن ، مثل توابع دیگر تا از تابع خارجی آن فراخوانی نشود ، اجرا نمیشود . مثل :
کد:
[FONT=tahoma]function Init(a,b,c)[/FONT]
[FONT=tahoma]function Sec(a,b)[/FONT]
[FONT=tahoma]ABC = a+b+5[/FONT]
[FONT=tahoma]return ABC[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]return Sec(a,b)[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Nm = Init(10,20,30)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", Nm, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
در مثال بالا ، تا زمانی که تابع داخلی آن (تابع Sec) از تابع خارجی آن (تابع Init) فراخوانی نشود ، تابع Sec اجرا نمیشود .
باید توجه داشت که بصورت مستقیم نمیتوانیم تابع داخلی یک تابع را فراخوانی کنیم چون تابع اجرا نشده و تا تابعی اجرا نشود (و کلا هر مقداری در لوا تعریف نشود) ، مقدارش nil است یعنی در مثال بالا نمی توانیم این جوری فراخوانیکنیم :
کد:
[FONT=tahoma]function Init(a,b,c)[/FONT]
[FONT=tahoma]function Sec(a,b)[/FONT]
[FONT=tahoma]ABC = a+b+5[/FONT]
[FONT=tahoma]return ABC[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]return Sec(a,b)[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Nm = Sec(10,20)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", Nm, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
4) بدست آوردن تعداد مقادیر بازگشتی یک تابع (select) :
برای درک تعداد مقادیر بازگشتی یک تابع ، میتوانید از تابع select (تابع اصلی لوا) کمک بگیرید
اولین آرگومان (ورودی) این تابع شماره ی متغییر (آرگومان) ای را میدهیم که در آرگومانهای بعدی این تابع نوشتیم . مثلا در مثال زیر :
کد:
[FONT=tahoma]value = select(2,"hello","word",67,"string",87)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", value, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
چون در آرگومان اول ، عدد 2 آورده شد ، یعنی دومین آرگومان بعد از خودش (به غیر از خودش) را برگردان (یعنی سومین آرگومان) که میشود رشته ی word
در مثال زیر :
کد:
[FONT=tahoma]function func(first,secand)[/FONT]
[FONT=tahoma]first=first+1[/FONT]
[FONT=tahoma]secand=secand-1[/FONT]
[FONT=tahoma]return first,secand[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Dialog.Message("Notice", select(2,func(5,2)), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
چون تابع func ، دو مقدار را برمیگرداند ، پس 2 مقدار در دو آرگومان تابع select ذخیره میشود (اولیین آرگومان تابع select که عدد 2 هست و دومین آرگومان که همان اولین مقدار بازگشتی تابع func (مقدار first) و سومین آرگومان هم برابر دومین مقدار بازگشتی تابع func (مقدار secand) است) پس معلوم است که خروجی تابع select ، یکی بعد از اولین آرگومان(که 2 است) یعنی سومین آرگومان تابع select که مقدار secand (که مقدارش 1 هست) میباشد
مثال بالا برابر است با مثال زیر :
کد:
[FONT=tahoma]function func(first,secand)[/FONT]
[FONT=tahoma]first=first+1[/FONT]
[FONT=tahoma]secand=secand-1[/FONT]
[FONT=tahoma]return first,secand[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]One,Two = func(5,2)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", select(2,One,Two), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
اگر بجای اولین تابع select ، بجای شماره (عدد) ، رشته ی "#" را قرار دهیم ، تعداد آرگومان هایی که در آن وجود دارد را باز میگرداند . پس برای بدست آوردن تعداد مقادیر بازگشتی یک تابع ، کافیست در اولین آرگومان تابع select ، رشته ی "#" و در دومین آرگومانش ، تابع مورد نظر را فراخوانی کنیم . پس برای بدیت آوردن تعداد بازگشتی تابع func در مثال اول ، کافیست :
کد:
[FONT=tahoma]function func(a,b)[/FONT]
[FONT=tahoma]Val1 = a+b[/FONT]
[FONT=tahoma]Val2=a*b[/FONT]
[FONT=tahoma]Val3 = a-b[/FONT]
[FONT=tahoma]return Val1,Val2,Val3[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Dialog.Message("Notice", select("#",func(5,2)), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
نکته : برای متوجه شدن تعداد مقادیر بازگشتی یک تابع ، از این روش استفاده میکنیم ولی برای متوجه شدن تعداد یک آرایه این تابع کارایی ندارد . برای این منظور کافیست علامت # (دقت کنید که این بار رشته نیست) را کنار اسم آرایه بگذارید (اما دقت کنید که این روش برای آرایه ها،در مواردی که عضو آرایه ها بصورت عدد نباشند (بصورت index نباشند) و با حروف تعریف شوند ، جواب نمیدهد که در این صورت باید از تابع Table.Count از AMS استفاده کنید وگرنه در لوا باید از تابع pairs در iterator ها (در مقاله های بعد ، آموزش ایتریتورها گفته خواهد شد) ، استفاده کنید)
5) استفاده از علامت آندرلاین _ برای متغییرهای بلا استفاده :
گاهی داخل بعضی از الگوریتم ها ، برای توابعی که چندین مقدار بازگشتی دارند ، از علامت آندرلاین _ برای آن متغییر استفاده میشود (یا با همان تابع select میتوان بهتر مدیریت کرد) . هر چند این متغییر هم مثل متغییرهای عادی قابل استفاده هست و فرقی ندارد که بجای آن ، از اسمی دیگر استفاده کرد :
کد:
[FONT=tahoma]_,s = string.find("This is Lua in", "Lua")[/FONT]
[FONT=tahoma]Dialog.Message("Notice", s, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
که در اینجا متغییر اول تابع string.find ، که با _ مشخص شد ، استفاده نمیکنند (البته میشود استفاده هم کرد مثل بقیه ی متغییرها)
6) تابع با ورودی و آرگومان متفاوت :
برای تعریف تابع (و هر آرگومان دیگر) که تعداد آرگومان هایش از قبل مشخص نباشند ، از علامت سه تا نقطه ... استفاده میشود . بعد ورودی ها را داخل آرایه میریزیم و بعد با بدست آوردن تعداد آن (که با علامت # مشخص میشد) ، به الگوریتم مان میپردازیم :
کد:
[FONT=tahoma]function average(...)[/FONT]
[FONT=tahoma]result = 0[/FONT]
[FONT=tahoma]local arg={...}[/FONT]
[FONT=tahoma]for i,v in pairs(arg) do[/FONT]
[FONT=tahoma]result = result + v[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]return result/#arg[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]برای فراخوانی و استفاده هم :[/FONT]
[FONT=tahoma]Debug.Print(average(1,4,3,5,4).."\r\n"); --result = 3.5[/FONT]
[FONT=tahoma]Debug.Print(average(1,4,5,4,4,3,7,8,9,4,2,9).."\r\n"); --result = 5[/FONT]
[FONT=tahoma]Debug.Print(average(2,9)); --result = 5.5[/FONT]
[FONT=tahoma]Debug.ShowWindow(true);[/FONT]
7) تابع بی نام :
این نوع تابع که اسم ندارد ، اغلب زمانی به کار میاید که بعد از تعریف ، فورا اجرایش کنیم . البته به ندرت این نوع توابع رو در مثال ها میبینیم.
ساختارش هم مثل تابع معمولی است و فقط اسم ندارد به اضافه ی اینکه قبل تعریف تابع ، یک پرانتز باز میکنیم و بعد آن پرانتز را میبندیم و بلافاصله بعدش مثل اجرای همه ی توابع که نشانه ی شان (بعد از فراخوانی اسم تابع که آرگومان ها را مینویسیم) دو پرانتز است ، دو پرانتز را باز و میبندیم که نشانه ی اجرای تابع تعریف شده باشد .
ساختارش به شکل زیر است :
کد:
[FONT=tahoma](function ()[/FONT]
[FONT=tahoma]end)()[/FONT]
[FONT=tahoma]مثلا :[/FONT]
[FONT=tahoma](function (a,b)[/FONT]
[FONT=tahoma]a=a*a[/FONT]
[FONT=tahoma]Dialog.Message("Notice", a, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
[FONT=tahoma]end)(6,7)[/FONT]
8) تبدیل رشته به تابع (loadstring) :
تابع loadstring که جزء توابع اصلی لواست ، رشته را به عنوان ورودی دریافت و به تابع قابل اجرا تبدیل میکند (البته اگر رشته ها طبق قواعد لوا یا AMS تعریف شده باشند)
چون مقدار بازگشتی اش تابع هست ، پس برای اجرای آن مثل همه ی توابع ، آخرش باید علامت تابع (که در نکته ی 7 گفته شد دو علامت پرانتز هست) گذاشته شود
نکته ی جالب توجه اینکه بعد از اجرای این تابع ، مقدار بازگشتی اش (مقدار بازگشتی loadstring بعد از اجرا) ، nil میشود
نکته ی بعد اینکه در لوا برای تعریف رشته هم از علامت " " و هم از علامت ' ' و هم از علامت [[ ]] استفاده میشود
در مثال زیر ، قبل از اجرا شدن تابع loadstring ، میتوانید نوع بازگشتی آنرا که تابع هست ، ببینید :
کد:
[FONT=tahoma]Qw=[[[/FONT]
[FONT=tahoma]a=5[/FONT]
[FONT=tahoma]c=a*4[/FONT]
[FONT=tahoma]Dialog.Message("Notice", "in anonymous function!\n"..c, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
[FONT=tahoma]]][/FONT]
[FONT=tahoma]x=loadstring(Qw)[/FONT]
[FONT=tahoma]Dialog.Message("Notice", type(x), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
در مثال زیر هم (که با گذاشتن علامت دو پرانتز ، آخر تابع loadstring به منظور اجرای تابع بازگشتی آن) ، رشته ی اصلی را اجرا کنید و بعد ، نوع بازگشتی را که قبلا اجرا function یا تابع بود و بعد از اجرا که nil میشود را ببینید :
کد:
[FONT=tahoma]Qw=[[[/FONT]
[FONT=tahoma]a=5[/FONT]
[FONT=tahoma]c=a*4[/FONT]
[FONT=tahoma]Dialog.Message("Notice", "in anonymous function!\n"..c, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
[FONT=tahoma]]][/FONT]
[FONT=tahoma]x=loadstring(Qw)()[/FONT]
[FONT=tahoma]Dialog.Message("Notice", type(x), MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
9) استفاده از حلقه در تابع :
اگر در تابعی ، حلقه ای بکار رود که داخل آن حلقه ، مقدار بازگشتی (return) برای تابع لحاظ شود ، آن تابع دیگر تکرار نمیشود با آنکه حلقه ی تکرار در آن وجود دارد مثل :
کد:
[FONT=tahoma]function DontRept()[/FONT]
[FONT=tahoma]for i=1,5 do[/FONT]
[FONT=tahoma]Dialog.Message("Notice", i, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
[FONT=tahoma]return i[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]DontRept()[/FONT]
اما اگر مقدار بازگشتی خارج از آن حلقه تعریف شود ، موردی ندارد و تابع تکرار میشود مثل :
کد:
[FONT=tahoma]function Rept()[/FONT]
[FONT=tahoma]for i=1,5 do[/FONT]
[FONT=tahoma]Dialog.Message("Notice", i, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]return i[/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Rept()[/FONT]
10) فراخوانی تابع با تک آرگومان آرایه ای :
اگر تابعی تعریف کنیم که فقط یک آرگومان آن هم از نوع آرایه داشته باشد (نه چندین آرگومان) ، میتوانیم علامت تابع یعنی پرانتز را هنگام فراخوانی نگذاریم یعنی :
کد:
[FONT=tahoma]function Ty(Arr1)[/FONT]
[FONT=tahoma]return Arr1[2][/FONT]
[FONT=tahoma]end[/FONT]
[FONT=tahoma]Dialog.Message("Notice", Ty{560,"salam"}, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
11) ایجاد و فراخوانی آرایه به روشی دیگر :
اگر آرایه ای داشته باشیم که key (یا به اصطلاح سمت چپ تساوی آن ، در متغییری ذخیره شده باشد) ، مثل متغییر foo و x و y در آرایه ی زیر :
کد:
[FONT=tahoma]t={foo="bar",x=5,y=true}[/FONT]
به 2 حالت میشود آنرا فراخوانی کرد که اول به این گونه:
کد:
[FONT=tahoma]t.foo[/FONT]
[FONT=tahoma]t.x[/FONT]
[FONT=tahoma]t.y[/FONT]
برابر است با نوع دوم اش به این گونه :
کد:
[FONT=tahoma]t["foo"][/FONT]
[FONT=tahoma]t["x"][/FONT]
[FONT=tahoma]t["y"][/FONT]
برای ایجاد آرایه هم میشود key ها را بصورت در هم شماره بندی و مقدار دهی کرد یعنی :
کد:
[FONT=tahoma]t={[3]=12,[7]="salam",[1]="word",[10]=653}[/FONT]
[FONT=tahoma]Dialog.Message("Notice", t[1].."\n"..t[3].."\n"..t[7].."\n"..t[10], MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);[/FONT]
که [1]t برابر رشته ی "word" و [3]t برابر 12 و [7]t برابر رشته ی "salam" و [10]t برابر 653 هست . توجه کنیم که در این حالت بقیه ی مقادیر nil هست مثل [2]t و ... و هم اینکه نباید در این حالت که همه ی key ها شماره گذاری شده اند ، بعضی از آنها را شماره گذاری نکنیم مثلا این طور صحیح نیست :
کد:
[FONT=tahoma]t={[3]=12,"salam",[1]="word",653[/FONT]
آخرین ویرایش: