title | actions | material | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
تفاوت Storage و Memory |
|
|
Storage به متغیرهایی گفته می شود که به طور دائمی در زنجیره بلوک ذخیره می شوند. Memory متغیرها موقتی هستند و بین فراخوانی های خارجی توابع قرارداد شما، پاک می شوند. به آن مانند دیسک سخت و RAM در کامپیوترتان فکر کنید.
بیشتر اوقات نیازی به استفاده از این کلمات کلیدی نیست زیرا Solidity به طور پیش فرض آنها را کنترل می کند. متغیرهای State (متغیرهای اعلام شده در خارج از توابع) بصورت پیش فرض storage
هستند و برای همیشه در بلاکچین نوشته می شوند ، در حالی که متغیرهای اعلام شده در داخل توابع memory
هستند و با پایان دادن به فراخوانی تابع از بین می روند.
با این حال ، مواردی وجود دارد که شما مجبور به استفاده از این کلمات کلیدی هستید ، به عنوان مثال در هنگام برخورد با structs و arrays در توابع:
contract SandwichFactory {
struct Sandwich {
string name;
string status;
}
Sandwich[] sandwiches;
function eatSandwich(uint _index) public {
// Sandwich mySandwich = sandwiches[_index];
// ^ Seems pretty straightforward, but solidity will give you a warning
// telling you that you should explicitly declare `storage` or `memory` here.
// So instead, you should declare with the `storage` keyword, like:
Sandwich storage mySandwich = sandwiches[_index];
// ...in which case `mySandwich` is a pointer to `sandwiches[_index]`
// in storage, and...
mySandwich.status = "Eaten!";
// ...this will permanently change `sandwiches[_index]` on the blockchain.
// If you just want a copy, you can use `memory`:
Sandwich memory anotherSandwich = sandwiches[_index + 1];
// ...in which case `anotherSandwich` will simply be a copy of the
// data in memory, and...
anotherSandwich.status = "Eaten!";
// ...will just modify the temporary variable and have no effect
// on `sandwiches[_index + 1]`. But you can do this:
sandwiches[_index + 1] = anotherSandwich;
// ...if you want to copy the changes back into blockchain storage.
}
}
اگر هنوز به درستی نمی دانید که از کدام یک استفاده کنید ، نگران نباشید - در طول این آموزش ما به شما می گوییم که چه زمانی از storage
استفاده کنید و چه زمانی از memory
استفاده کنید ، و کامپایلر Solidity نیز به شما هشدارهایی در این مورد به شما می دهد که چه زمانی باید از یکی از این کلمات کلیدی استفاده کنید.
در حال حاضر ، کافی است بدانید که مواردی وجود دارد که شما باید صریحاً storage
یا memory
را اعلام کنید!
وقت آن است که به زامبی های خود توانایی تغذیه و تکثیر را بدهیم!
وقتی یک زامبی از برخی از شکل های زندگی دیگر تغذیه کند ، DNA آن با DNA شکل زندگی دیگر ترکیب می شود و یک زامبی جدید ایجاد می کند.
-
تابعی به نام
feedAndMultiply
ایجاد کنید. این تابع دو پارامتر ورودی خواهد داشت:_zombieId
(از نوعuint
) و_targetDna
(همچنینuint
). این تابع بایدpublic
باشد. -
ما نمی خواهیم اجازه دهیم شخص دیگری با استفاده از زامبی ما تغذیه کند! بنابراین اول ، بیایید مطمئن شویم که مالک این زامبی هستیم. برای اطمینان از اینکه
msg.sender
برابر با صاحب این زامبی است ، عبارتrequire
را اضافه کنید (شبیه کاری که در عملکردcreateRandomZombie
انجام دادیم).
توجه: مجدداً ، به دلیل اینکه بررسی جواب ما ابتدایی است ، انتظار می رود که ابتدا
msg.sender
بیاید و در صورت تغییر ترتیب ، آن را اشتباه علامت گذاری می کند. اما به طور معمول هنگام کدگذاری ، می توانید از هر ترتیبی که ترجیح می دهید استفاده کنید - هر دو درست هستند.
- لازم است DNA این زامبی را بدست آوریم. بنابراین کار بعدی که تابع ما باید انجام دهد این است که یک
Zombie
محلی به نامmyZombie
اعلام کنید (که یک اشاره گرstorage
خواهد بود). این متغیر را در آرایهzombies
ما برابر با index_zombieId
قرار دهید.
شما باید 4 خط کد داشته باشید ، که شامل علامت }
برای بسته شدن تابع است.
ما در درس بعدی به کارگیری این تابع ادامه خواهیم داد!