در این بخش، با ساختار داده ای آرایه (Array) و رشته (String) در سالیدیتی آشنا میشویم. این دو رفتار متفاوتی نسبت به انواع داده ای ساده ای که پیش تر بررسی کردیم دارند، بنابراین به طور جداگانه به آنها میپردازیم.
آموزش آرایه ها و رشته ها در سالیدیتی
بیاید در این مطلب نحوه تعریف آرایه ها (Syntax for Declaring Arrays) رو توضیح دهیم. ابتدا به تابعی که یک آرایه را دریافت کرده و همان آرایه را بازمیگرداند نگاه کنیم. در اینجا نکات زیادی وجود دارد که باید توضیح داده شود.
ابتدا توجه کنید که نحوهی تعریف یک آرایه از اعداد صحیح، به این صورت است: uint256[]
. (در ادامه دربارهی calldata
و memory
نیز صحبت خواهیم کرد.)
1 2 3 4 5 6 7 8 |
contract ExampleContract { function useArrayForUint256(uint256[] calldata input) public pure returns (uint256[] memory) { return input; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
contract ExampleContract { function booleanArrayExample(bool[] calldata input) public pure returns (bool[] memory) { return input; } function addressArrayExample(address[] calldata input) public pure returns (address[] memory) { return input; } } |
منظور از calldata
و memory
چیست؟
اگر calldata
یا memory
را مشخص نکنید، کد شما کامپایل نخواهد شد. برای مثال، دو کد زیر به دلیل عدم مشخص کردن calldata
یا memory
با خطا مواجه میشوند:
1 2 3 4 5 6 7 8 9 |
contract BadContract1 { // آرگومان فاقد calldata است function useArrayForUint256(uint256[] input) public pure returns (uint256[] memory) { return input; } } |
1 2 3 4 5 6 7 8 9 |
contract BadContract2 { // نوع بازگشتی فاقد memory است function useArrayForUint256(uint256[] calldata input) public pure returns (uint256[]) { return input; } } |
توضیح memory
و calldata
:
-
memory
در سالیدیتی مشابه حافظهی هیپ (heap) در زبانهای C، C++ یا Rust عمل میکند. چون آرایهها میتوانند اندازهی دلخواهی داشته باشند، نگهداری آنها روی استک میتواند باعث خطای Stack Overflow شود. -
calldata
ویژگی خاصی از solidity است و به دادههای ارسالی در یک تراکنش بلاکچین اتریوم اشاره دارد. وقتی آرگومانی به صورتcalldata
تعریف میشود، به دادههای تراکنش اصلی رجوع میکند.
نکته: اگر مطمئن نیستید، برای آرگومانهای آرایهها و رشتهها از
calldata
و برای مقادیر بازگشتی ازmemory
استفاده کنید.
پس calldata
و memory
چه هستند؟
اگر با زبانهای C یا ++C آشنا باشید، این مفهوم برایتان آشنا خواهد بود. memory
در سالیدیتی شبیه به حافظهی heap در زبانهایی مثل C، ++C یا Rust است. آرایهها میتوانند اندازهی نامحدودی داشته باشند، بنابراین اگر آنها را روی استک اجرایی (execution stack) ذخیره کنیم (نگران نباشید اگر نمیدانید استک چیست)، ممکن است باعث بروز خطای stack overflow شوند (البته این خطا با سایت معروف Stack Overflow فرق دارد!).
اما calldata
چیزی است که مخصوص سالیدیتی است. calldata
در واقع همان “اطلاعات تراکنشی” است که وقتی کسی یک تراکنش به بلاکچین ارسال میکند، همراه آن تراکنش فرستاده میشود.
پس calldata
یعنی “ارجاع به دادههای تراکنش اتریوم”. این موضوع نسبتاً پیشرفته است، پس اگر الان کامل متوجه نشدید، اشکالی ندارد.
یک قاعدهی ساده: اگر در تابعی آرایه یا رشته (string) را به عنوان ورودی دریافت میکنید، بهتر است از calldata
استفاده کنید. اما اگر آرایه یا رشتهای را از تابع برمیگردانید (return)، باید از memory
استفاده کنید.
البته در استفاده از calldata
برای ورودی توابع استثناهایی هم وجود دارد، اما برای خروجی توابع، همیشه باید memory
باشد، وگرنه کد شما کامپایل نمیشود. برای اینکه اطلاعات زیادی یکباره به شما ندهیم، دربارهی این استثناها بعداً صحبت خواهیم کرد.
در ادامه میبینیم چطور میتوانیم از آرایههای عددی در Remix استفاده کنیم.
پیمایش آرایهها در Remix
آرایهها در سالیدیتی همانند اکثر زبانهای دیگر از اندیس صفر شروع میشوند (zero-indexed). در این مثال، اولین عنصر آرایه بازگردانده میشود:
1 2 3 4 5 6 7 8 9 |
contract ExampleContract { function returnFirstElement(uint256[] calldata myArray) public pure returns (uint256) { uint256 first = myArray[0]; return first; } } |
توجه: اگر آرایه خالی باشد، تراکنش بازخواهد گشت (revert خواهد شد).
گرفتن طول آرایه در Solidity
برای بهدست آوردن طول آرایه از .length
استفاده میکنیم (مشابه جاوااسکریپت):
1 2 3 4 5 6 7 8 9 |
contract ExampleContract { function returnFirstElement(uint256[] calldata myArray) public pure returns (uint256) { uint256 len = myArray.length; return len; } } |
پیمایش آرایه با حلقهی for در سالیدیتی
به این شکل میتوانید روی یک آرایه حلقه بزنید.
1 2 3 4 5 6 7 8 9 10 11 12 |
contract ExampleContract { function productOfarray(uint256[] calldata myArray) public pure returns (uint256) { uint256 product = 1; for (uint256 i = 0; i < myArray.length; i++) { product *= myArray[i]; } return product; } } |
آرایه با طول ثابت در سالیدیتی
در مثالهای قبلی، در هنگام تعریف، چیزی داخل براکتها قرار نمیگرفت. اگر میخواهید اندازه یک آرایه را ثابت نگه دارید، میتوانید اندازه را داخل براکتها قرار دهید.
1 2 3 4 5 6 7 8 9 |
contract ExampleContract { function productOfarray(uint256[5] calldata myArray) public pure returns (uint256) { uint256 last = myArray[4]; return last; } } |
اگر آرایهای با طولی غیر از ۵ ارسال شود، تراکنش با خطا مواجه خواهد شد.
رشتهها (Strings) در سالیدیتی
رشتهها رفتار بسیار مشابهی با آرایهها دارند. در واقع، رشتهها زیرساختی مشابه آرایهها دارند (هرچند تفاوتهایی نیز وجود دارد).
تابعی برای بازگرداندن رشته
در اینجا تابعی را مشاهده میکنید که رشتهای را که به آن ارسال کردهاید، برمیگرداند:
1 2 3 4 5 6 7 8 |
contract ExampleContract { function echo(string calldata input) public pure returns (string memory) { return input; } } |
و بلاخره Hello World اینجاست!
1 2 3 4 5 6 7 8 |
contract ExampleContract { function helloWorld() public pure returns (string memory) { return "Hello, world!"; } } |
اتصال (چسباندن) رشتهها
سالیدیتی تا فوریه ۲۰۲۲ (نسخهی 0.8.12) از اتصال رشتهها (string concatenation) پشتیبانی نمیکرد. اگر میخواهید رشتهها را به هم متصل کنید، مطمئن شوید که pragma در بالای فایل حداقل ۰.۸.۱۲ باشد.
1 2 3 4 5 6 7 8 9 |
pragma solidity ^0.8.12; contract ExampleContract { function useArrays(string calldata user) public pure returns(string memory) { return string.concat("hello ", user); } } |
دلیل اضافه شدن دیرهنگام این قابلیت این است که قراردادهای هوشمند معمولاً با اعداد سروکار دارند، نه رشتهها.
محدودیتهای رشتهها در سالیدیتی
-
عدم امکان ایندکسدهی به رشتهها:
در سالیدیتی نمیتوانید با استفاده از ایندکس به کاراکتر خاصی از یک رشته دسترسی پیدا کنید. این کد کامپایل نخواهد شد:
1 2 3 4 5 6 7 8 9 |
pragma solidity ^0.8.12; contract BadContract { function useArrays(string calldata input) public pure returns(string memory) { return input[0]; // خطا } } |
- عدم پشتیبانی از طول رشته:
برخلاف آرایهها، نمیتوانید مستقیماً طول یک رشته را در سالیدیتی بهدست آورید. دلیل این محدودیت، نحوهی نمایش رشتهها به صورت آرایهای از بایتها (byte array) و پیچیدگیهای مرتبط با یونیکد است.
1 2 3 4 5 6 7 8 9 |
pragma solidity ^0.8.12; contract StringContract { function useArrays(string calldata input) public pure returns(uint256) { return input.length; // does not compile } } |
نکاتی که هنوز توضیح داده نشدهاند
-
آرایهها در سالیدیتی دارای عملیاتهایی مانند
pop()
هستند، اما این عملیاتها تاثیرات جانبی (side-effects) دارند و در مراحل پیشرفتهتر به آنها خواهیم پرداخت. -
تعریف آرایهها و رشتهها درون خود تابع (و نه به عنوان آرگومان یا مقدار بازگشتی)، دارای نحو (syntax) متفاوتی است که بعداً معرفی خواهد شد.
امیدوارم آموزش آرایه ها و رشته ها در سالیدیتی مفید واقع شده باشد.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- منبع : سورس باران
- رمز فايل : www.sourcebaran.com
- انتشار: ۹ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس