مالکیت و قرض گرفتن – انجمن DEV

Summarize this content to 400 words in Persian Lang
در این وبلاگ به شما اطلاع خواهم داد که Rust چه تفاوتی با زبان های دیگر دارد، از زبان های سطح بالا تا سطح پایین که ما در بازار داریم.
اما اولاً جالب است که شما قبلاً در مورد اساس آن مانند انواع آن و غیره ایده دارید.شروع کنیم!
شاید قبلاً می دانید که یکی از چالش های اصلی ما در برنامه نویسی مدیریت حافظه Heap، مدیریت معروف است.در اینجا به موضوع وبلاگ خود می پردازیم، افراد مالکیت و وام گیرنده می آیند تا این واقعیت را دور بزنند.
هنگامی که ما با Rust کامپایل می کنیم، Borrow Checker به تصویر می کشد که آیا کاری که ما انجام می دهیم در مورد مدیریت حافظه درست است یا خیر، “حتی کامپایل هم نمی شود”.
در برنامه نویسی ما این سری مشکلات را داریم که Borrow Checker به آنها پرداخته است.
استثنای اشاره گر تهی
خطای تقسیم بندی
نشت حافظه
اشاره گر دانپلینگ
دو برابر رایگان
بعد رایگان استفاده کنید
مسابقه داده ها
اگر کمی در مورد Borrow Checker صحبت کنیم، وقتی با این خطاها سروکار داریم، رفتار جالبی دارد، فقط تابع را می گیرد و معنی آن چیست؟
این بدان معنی است که جستجوگر قرض با سطح عملکرد همراه است و بر عملکردی که روی آن کار می شود تمرکز می کند و زندگی ما را آسان تر می کند.
در Rust، جالب است که سیستم نوع را درک کنید، به عنوان مثال، انواع کپی، انواعی که می توانند به طور خودکار کپی شوند. مثلا.
fn main() {
let mut a: i32 = 1; // i32 é um tipo Copy
let b: = a;
println!(“Olá, o valor de A inicial = {}”, a);
println!(“Olá, o valor de B inicial = {}”, b);
a = 21;
println!(“Olá, o valor de A final = {}”, a);
println!(“Olá, o valor de B final = {}”, b);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
انواع کپی این امکان را فراهم می کند، Rust یک کپی ایجاد می کند، بر خلاف زبان های دیگر که مرجع هستند، هنگام استفاده از این کپی این رفتار امکان پذیر است. Rust یک مقدار جدید 1 ایجاد می کند، این مقدار بر خلاف یک نمونه جدید اکنون b است. با در نظر گرفتن این استقلال، هنگام اجرای کد بالا، این نتیجه را خواهید داشت.
Olá, o valor de A inicial = 1
Olá, o valor de B inicial = 1
Olá, o valor de A final = 21
Olá, o valor de B final = 1
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
حالا فکر کنید که نمیخواهید یک کپی ایجاد کنید، وقتی مقدار a به b را میپذیرید، یک مرجع به صورت دستی ایجاد میکنید.
fn main() {
let a: i32 = 1; // i32 é um tipo Copy
let b = &a;
println!(“Olá, o valor de A inicial = {}”, a);
println!(“Olá, o valor de B inicial = {}”, b);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
هنگام اجرای این کد کوچک، خواهید دید که یک مرجع از 'b' به 'a' ایجاد شده است، اکنون، اگر بخواهم مقدار 'a' را تغییر دهم، مقدار 'b' تغییر خواهد کرد.
اما ابتدا باید متغیر را تغییرپذیر کنیم. همانطور که میخواهیم مقدار یک متغیر را تغییر دهیم، یک نوع داده داریم که امکان تغییرپذیری را فراهم میکند، مانند «Refcell» برای مثال، اگرچه «&mut» نیز دارد، بنابراین یک مرجع قابل تغییر ایجاد میکند.
fn main() {
let a = RefCell::new(1);// i32 é um tipo Copy
let b = &a;
println!(“Olá, o valor de A inicial = {}”, a.borrow());
println!(“Olá, o valor de B inicial = {}”, b.borrow());
*a.borrow_mut() = 11;
println!(“Olá, o valor de A inicial = {}”, a.borrow());
println!(“Olá, o valor de B inicial = {}”, b.borrow());
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مقدار 'a' مجاز به تغییر است. در روش “borrow()” برای به دست آوردن یک مرجع تغییرناپذیر به مقدار استفاده شد. متد ()borrow_mut برای به دست آوردن یک مرجع قابل تغییر استفاده می شود.
از این نظر، خروجی به صورت زیر خواهد بود:
Olá, o valor de A inicial = 1
Olá, o valor de B inicial = 1
Olá, o valor de A inicial = 11
Olá, o valor de B inicial = 11
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
این یکی از راه هایی بود که برای انجام این عملیات وجود دارد.بیایید اکنون نحوه استفاده از حافظه Heap را درک کنیم!
در اینجا ما مفهوم را وارد می کنیم، هنگام استفاده از String، به طور خودکار آن را به حافظه Heap اختصاص می دهیم، و آن را در اختیار داشتن 'a'، چیزی شبیه به 'Owner' می کنیم. متغیر “a” صاحب “پاتو” است.
fn main() {
let a = String::from(“Pato”); // String está alocada na Heap
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
o que seria o قرض ارزش جابجا شده؟
شما از String استفاده میکنید، مقدار به Heap اختصاص داده میشود و بهطور پیشفرض نمیتوان آن را کپی کرد، اما ما میخواهیم «b» مقدار «a» را داشته باشد. در این سناریوها، “Move” اتفاق می افتد، مقدار “a” به “b” منتقل می شود، هنگام اجرای این کد کوچک متوجه خواهید شد که با خطا مواجه خواهید شد.
fn main() {
let a = String::from(“Pato”); // String está alocada na Heap
let b = a; // ‘Move’ movendo a para b
println!(“O valor de A é {}”, a);
println!(“O valor de B é {}”, b);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
O erro:
Compiling array_element_acess v0.1.0 (/home/marlon/projects/array_element_acess)
error[E0382]: borrow of moved value: `a`
–> src/main.rs:4:35
|
2 | let a = String::from(“Pato”); // String está alocada na Heap
| – move occurs because `a` has type `String`, which does not implement the `Copy` trait
3 | let b = a; // movendo a para b
| – value moved here
4 | println!(“O valor de A é {}”, a);
| ^ value borrowed here after move
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
توجه داشته باشید که اکنون میخواهیم به مقداری دسترسی پیدا کنیم که قبلاً به b منتقل شده است، وقتی زبانهایی داریم که از کلکتور استفاده میکنند، این خطاها رخ نمیدهد، اما در اینجا، وقتی از Move استفاده میکنیم، Rust اجازه آن را نمیدهد. .
اکنون، برای حل این مشکل، میتوانیم «وام» را انجام دهیم، که عبارت «&» را به جایی که میخواهیم منتقل میکند، اکنون مقدار دیگر جابهجا نمیشود، «وام» است.
fn main() {
let a = String::from(“Pato”); // String está alocada na Heap
let b = &a; //Empreste para b
println!(“O valor de A é {}”, a);
println!(“O valor de B é {}”, b);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
وقتی این کد را اجرا کنید، این نتیجه را دریافت خواهید کرد
O valor de A é Pato
O valor de B é Pato
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
قوانین Onwership در Rust چیست؟
هر ارزش صاحبی دارد
فقط می تواند یک مالک داشته باشد
وقتی مالک از محدوده خارج می شود، مقدار پاک می شود
مالکیت را می توان به مالک دیگری منتقل کرد
کارکرد
هنگام استفاده از &str، ما از یک نوع Copy استفاده می کنیم و همانطور که قبلاً دیدیم، آنچه اتفاق می افتد این است که یک کپی ایجاد می شود.
fn say_hello(text: &str) {
println!(“Hello, {text}”);
}
fn say_goodbye(text: &str){
println!(“Goodbye, {text}”);
}
fn main() {
let name = “Pato”; // static, str é do tipo Copy
say_hello(name);
say_goodbye(name);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
هنگام اجرای این کد، این پاسخ برگردانده می شود:
Hello, Pato
Goodbye, Pato
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
حالا برای استفاده از حافظه Heap چه کاری می توانیم انجام دهیم؟اکنون میتوانیم «&str» را برای رشته حذف کنیم.
برای ایجاد یک کپی در حافظه Heap، باید از 'clone()' استفاده کنید، این کار هزینه بر است، بنابراین مراقب باشید که در Heap چه کاری انجام می دهید.
fn say_hello(text: String) {
println!(“Hello, {text}”);
}
fn say_goodbye(text: String){
println!(“Goodbye, {text}”);
}
fn main() {
let name = “Pato”.to_string();
say_hello(name.clone()); // Clone.
say_goodbye(name);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
در حال حاضر، راه بهتر برای حل این مشکل، استفاده از وام است، همانطور که قبلاً دیدیم
fn say_hello(text: &String) {
println!(“Hello, {text}”);
}
fn say_goodbye(text: &String){
println!(“Goodbye, {text}”);
}
fn main() {
let name = “Pato”.to_string();
say_hello(&name); // Borrow, Emprestar
say_goodbye(&name);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
ما فقط یک صاحب داریم!
قوانین وام گرفتن
اگر قابل تغییر باشد، می توانیم یک مرجع واحد داشته باشیم
زمانی که همه آنها تغییر ناپذیر باشند، می توانیم چندین داشته باشیم
در این کد جدید، ما در مورد وام صحبت می کنیم!
ما فقط یک صاحب داریم!قوانین وام گرفتن
اگر قابل تغییر باشد، می توانیم یک مرجع واحد داشته باشیم
زمانی که همه آنها تغییر ناپذیر باشند، می توانیم چندین داشته باشیم
در این کد جدید، ما در مورد وام صحبت می کنیم!`
امیدوارم کمی از مالکیت و قرض گرفتن لذت برده باشید، درک اینکه غیرقابل تغییر و تغییرپذیر چیست، وام ها، مالکان، برخی از مفاهیم مهم هستند، درک اینکه Move و Loans چیست در توسعه Rust بسیار مهم است.
در این وبلاگ به شما اطلاع خواهم داد که Rust چه تفاوتی با زبان های دیگر دارد، از زبان های سطح بالا تا سطح پایین که ما در بازار داریم.
اما اولاً جالب است که شما قبلاً در مورد اساس آن مانند انواع آن و غیره ایده دارید.
شروع کنیم!
شاید قبلاً می دانید که یکی از چالش های اصلی ما در برنامه نویسی مدیریت حافظه Heap، مدیریت معروف است.
در اینجا به موضوع وبلاگ خود می پردازیم، افراد مالکیت و وام گیرنده می آیند تا این واقعیت را دور بزنند.
هنگامی که ما با Rust کامپایل می کنیم، Borrow Checker به تصویر می کشد که آیا کاری که ما انجام می دهیم در مورد مدیریت حافظه درست است یا خیر، “حتی کامپایل هم نمی شود”.
در برنامه نویسی ما این سری مشکلات را داریم که Borrow Checker به آنها پرداخته است.
- استثنای اشاره گر تهی
- خطای تقسیم بندی
- نشت حافظه
- اشاره گر دانپلینگ
- دو برابر رایگان
- بعد رایگان استفاده کنید
- مسابقه داده ها
اگر کمی در مورد Borrow Checker صحبت کنیم، وقتی با این خطاها سروکار داریم، رفتار جالبی دارد، فقط تابع را می گیرد و معنی آن چیست؟
این بدان معنی است که جستجوگر قرض با سطح عملکرد همراه است و بر عملکردی که روی آن کار می شود تمرکز می کند و زندگی ما را آسان تر می کند.
در Rust، جالب است که سیستم نوع را درک کنید، به عنوان مثال، انواع کپی، انواعی که می توانند به طور خودکار کپی شوند. مثلا.
fn main() {
let mut a: i32 = 1; // i32 é um tipo Copy
let b: = a;
println!("Olá, o valor de A inicial = {}", a);
println!("Olá, o valor de B inicial = {}", b);
a = 21;
println!("Olá, o valor de A final = {}", a);
println!("Olá, o valor de B final = {}", b);
}
انواع کپی این امکان را فراهم می کند، Rust یک کپی ایجاد می کند، بر خلاف زبان های دیگر که مرجع هستند، هنگام استفاده از این کپی این رفتار امکان پذیر است. Rust یک مقدار جدید 1 ایجاد می کند، این مقدار بر خلاف یک نمونه جدید اکنون b است. با در نظر گرفتن این استقلال، هنگام اجرای کد بالا، این نتیجه را خواهید داشت.
Olá, o valor de A inicial = 1
Olá, o valor de B inicial = 1
Olá, o valor de A final = 21
Olá, o valor de B final = 1
حالا فکر کنید که نمیخواهید یک کپی ایجاد کنید، وقتی مقدار a به b را میپذیرید، یک مرجع به صورت دستی ایجاد میکنید.
fn main() {
let a: i32 = 1; // i32 é um tipo Copy
let b = &a;
println!("Olá, o valor de A inicial = {}", a);
println!("Olá, o valor de B inicial = {}", b);
}
هنگام اجرای این کد کوچک، خواهید دید که یک مرجع از 'b' به 'a' ایجاد شده است، اکنون، اگر بخواهم مقدار 'a' را تغییر دهم، مقدار 'b' تغییر خواهد کرد.
اما ابتدا باید متغیر را تغییرپذیر کنیم. همانطور که میخواهیم مقدار یک متغیر را تغییر دهیم، یک نوع داده داریم که امکان تغییرپذیری را فراهم میکند، مانند «Refcell» برای مثال، اگرچه «&mut» نیز دارد، بنابراین یک مرجع قابل تغییر ایجاد میکند.
fn main() {
let a = RefCell::new(1);// i32 é um tipo Copy
let b = &a;
println!("Olá, o valor de A inicial = {}", a.borrow());
println!("Olá, o valor de B inicial = {}", b.borrow());
*a.borrow_mut() = 11;
println!("Olá, o valor de A inicial = {}", a.borrow());
println!("Olá, o valor de B inicial = {}", b.borrow());
}
مقدار 'a' مجاز به تغییر است. در روش “borrow()” برای به دست آوردن یک مرجع تغییرناپذیر به مقدار استفاده شد. متد ()borrow_mut برای به دست آوردن یک مرجع قابل تغییر استفاده می شود.
از این نظر، خروجی به صورت زیر خواهد بود:
Olá, o valor de A inicial = 1
Olá, o valor de B inicial = 1
Olá, o valor de A inicial = 11
Olá, o valor de B inicial = 11
این یکی از راه هایی بود که برای انجام این عملیات وجود دارد.
بیایید اکنون نحوه استفاده از حافظه Heap را درک کنیم!
در اینجا ما مفهوم را وارد می کنیم، هنگام استفاده از String، به طور خودکار آن را به حافظه Heap اختصاص می دهیم، و آن را در اختیار داشتن 'a'، چیزی شبیه به 'Owner' می کنیم. متغیر “a” صاحب “پاتو” است.
fn main() {
let a = String::from("Pato"); // String está alocada na Heap
}
o que seria o قرض ارزش جابجا شده؟
شما از String استفاده میکنید، مقدار به Heap اختصاص داده میشود و بهطور پیشفرض نمیتوان آن را کپی کرد، اما ما میخواهیم «b» مقدار «a» را داشته باشد. در این سناریوها، “Move” اتفاق می افتد، مقدار “a” به “b” منتقل می شود، هنگام اجرای این کد کوچک متوجه خواهید شد که با خطا مواجه خواهید شد.
fn main() {
let a = String::from("Pato"); // String está alocada na Heap
let b = a; // 'Move' movendo a para b
println!("O valor de A é {}", a);
println!("O valor de B é {}", b);
}
O erro:
Compiling array_element_acess v0.1.0 (/home/marlon/projects/array_element_acess)
error[E0382]: borrow of moved value: `a`
--> src/main.rs:4:35
|
2 | let a = String::from("Pato"); // String está alocada na Heap
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
3 | let b = a; // movendo a para b
| - value moved here
4 | println!("O valor de A é {}", a);
| ^ value borrowed here after move
توجه داشته باشید که اکنون میخواهیم به مقداری دسترسی پیدا کنیم که قبلاً به b منتقل شده است، وقتی زبانهایی داریم که از کلکتور استفاده میکنند، این خطاها رخ نمیدهد، اما در اینجا، وقتی از Move استفاده میکنیم، Rust اجازه آن را نمیدهد. .
اکنون، برای حل این مشکل، میتوانیم «وام» را انجام دهیم، که عبارت «&» را به جایی که میخواهیم منتقل میکند، اکنون مقدار دیگر جابهجا نمیشود، «وام» است.
fn main() {
let a = String::from("Pato"); // String está alocada na Heap
let b = &a; //Empreste para b
println!("O valor de A é {}", a);
println!("O valor de B é {}", b);
}
وقتی این کد را اجرا کنید، این نتیجه را دریافت خواهید کرد
O valor de A é Pato
O valor de B é Pato
قوانین Onwership در Rust چیست؟
- هر ارزش صاحبی دارد
- فقط می تواند یک مالک داشته باشد
- وقتی مالک از محدوده خارج می شود، مقدار پاک می شود
- مالکیت را می توان به مالک دیگری منتقل کرد
کارکرد
هنگام استفاده از &str، ما از یک نوع Copy استفاده می کنیم و همانطور که قبلاً دیدیم، آنچه اتفاق می افتد این است که یک کپی ایجاد می شود.
fn say_hello(text: &str) {
println!("Hello, {text}");
}
fn say_goodbye(text: &str){
println!("Goodbye, {text}");
}
fn main() {
let name = "Pato"; // static, str é do tipo Copy
say_hello(name);
say_goodbye(name);
}
هنگام اجرای این کد، این پاسخ برگردانده می شود:
Hello, Pato
Goodbye, Pato
حالا برای استفاده از حافظه Heap چه کاری می توانیم انجام دهیم؟
اکنون میتوانیم «&str» را برای رشته حذف کنیم.
برای ایجاد یک کپی در حافظه Heap، باید از 'clone()' استفاده کنید، این کار هزینه بر است، بنابراین مراقب باشید که در Heap چه کاری انجام می دهید.
fn say_hello(text: String) {
println!("Hello, {text}");
}
fn say_goodbye(text: String){
println!("Goodbye, {text}");
}
fn main() {
let name = "Pato".to_string();
say_hello(name.clone()); // Clone.
say_goodbye(name);
}
در حال حاضر، راه بهتر برای حل این مشکل، استفاده از وام است، همانطور که قبلاً دیدیم
fn say_hello(text: &String) {
println!("Hello, {text}");
}
fn say_goodbye(text: &String){
println!("Goodbye, {text}");
}
fn main() {
let name = "Pato".to_string();
say_hello(&name); // Borrow, Emprestar
say_goodbye(&name);
}
ما فقط یک صاحب داریم!
قوانین وام گرفتن
- اگر قابل تغییر باشد، می توانیم یک مرجع واحد داشته باشیم
- زمانی که همه آنها تغییر ناپذیر باشند، می توانیم چندین داشته باشیم
در این کد جدید، ما در مورد وام صحبت می کنیم!
ما فقط یک صاحب داریم!
قوانین وام گرفتن
- اگر قابل تغییر باشد، می توانیم یک مرجع واحد داشته باشیم
- زمانی که همه آنها تغییر ناپذیر باشند، می توانیم چندین داشته باشیم
در این کد جدید، ما در مورد وام صحبت می کنیم!`
امیدوارم کمی از مالکیت و قرض گرفتن لذت برده باشید، درک اینکه غیرقابل تغییر و تغییرپذیر چیست، وام ها، مالکان، برخی از مفاهیم مهم هستند، درک اینکه Move و Loans چیست در توسعه Rust بسیار مهم است.