اشتراک‌ها
دانلود کتاب PowerShell

A quick start guide for IT professionals who want to learn about Windows PowerShell.  
 

دانلود کتاب PowerShell
اشتراک‌ها
مصاحبه‌ای با Anders Hejlsberg

An interview with Anders Hejlsberg: his origin story; how he created TypeScript, C#, Delphi and Turbo Pascal; open source; his daily workflow; his thoughts on AI, Solidity, Rust, and more. 

مصاحبه‌ای با Anders Hejlsberg
اشتراک‌ها
دوره 22 ساعته مهندسی بانک‌های اطلاعاتی

Database Engineering Complete Course | DBMS Complete Course
In this program, you’ll learn:
Core techniques and methods to structure and manage databases.
Advanced techniques to write database driven applications and advanced data modeling concepts.
MySQL database management system (DBMS) and data creation, querying and manipulation.
How to code and use Python Syntax
How to prepare for technical interviews for database engineer roles.
 

دوره 22 ساعته مهندسی بانک‌های اطلاعاتی
اشتراک‌ها
دوره فراگیری نحوه‌ی کار با Pinvoke در دات نت

Pinvoke for C# .NET Framework complete tutorial - May 2023 - 92418487
Complete course. How to expose to C# via pinvoke functions with C programming language signatures exported from DLLs. Use DependenciesGui.exe in order to see the functions exported by win32 API DLLs. Use the website pinvoke.net. How to write C# signatures for C programming language structs, enums, constants. How to wrap pinvoke method signatures in C# idiomatic methods. 

دوره فراگیری نحوه‌ی کار با Pinvoke در دات نت
اشتراک‌ها
DSL چیست؟

The complete guide to (external) Domain Specific Languages 

DSL چیست؟
اشتراک‌ها
Deno؛ پروژه‌ی جدید خالق Node.js

Ryan Dahl, the creator of Node.js, is currently working on Deno, a new runtime for JavaScript and TypeScript, built using V8, TypeScript, and Rust. A 30-minute overview talk. 

Deno؛ پروژه‌ی جدید خالق Node.js
مطالب
آموزش زبان Rust - قسمت 8 - Rust-Based CS Masterclass
مدیریت حافظه، نقش مهمی را در برنامه نویسی ایفا می‌کند و بر عملکرد و کارآیی یک برنامه تاثیر می‌گذارد. این مقاله، مروری را بر سه نوع حافظه‌ی اصلی ارائه می‌کند:  static memory, stack memory, heap . درک تفاوت بین این انواع حافظه‌ها می‌تواند به شما در بهینه سازی کد و جلوگیری از مشکلات احتمالی، کمک کند.


Static Memory

حافظه‌ی static برای ذخیره‌ی باینری‌های برنامه، متغیرهای استاتیک و حروف رشته‌ای (در Rust) استفاده می‌شود. اندازه‌ی حافظه استاتیک ثابت است و در زمان کامپایل مشخص می‌شود. حافظه‌ی استاتیک طول عمری برابر با عمر برنامه دارد و مقادیر آن از شروع، تا پایان برنامه، باقی می‌ماند. پاکسازی حافظه‌ی استاتیک به صورت خودکار انجام می‌شود و با پایان برنامه انجام می‌شود.

مواردی که در حافظه استاتیک قرار میگیرند :
  • Program Binary
  • Static variables
  • String Literals (in Rust)

Size :
  Fixed ( محاسبه در زمان کامپایل )
Lifetime : برابر با طول عمر برنامه
پاکسازی : به صورت خودکار ؛ زمانی که برنامه متوقف میشود .


  Stack Memory

حافظه‌ی پشته، مسئول نگهداری آرگومان‌های تابع و متغیرهای محلی است. پشته، شامل stack frames است که برای هر فراخوانی تابع در زنجیره‌ای از فراخوانی‌های تابع، ایجاد می‌شوند (به عنوان مثال، A B را فرا می‌خواند، B C را فرا می‌خواند). حافظه‌ی پشته به اندازه‌ی مشخصی در زمان کامپایل نیاز دارد؛ به این معنا که آرگومان‌ها و متغیرهای درون  stack frames باید اندازه‌های از پیش تعیین شده‌ای داشته باشند. اندازه‌ی پشته، پویا است؛ اما دارای حد بالایی ثابتی است که در هنگام راه اندازی برنامه تعریف شده‌است. حافظه‌ی پشته، دارای طول عمری برابر با طول عمر عملکرد است و هنگامیکه عملکرد، نتیجه‌ای را بر می‌گرداند، پاکسازی آن خودکار است.  

بیایید نگاهی به یک مثال ساده در Rust بیندازیم تا حافظه‌ی پشته را بهتر درک کنیم:
fn add(x: i32, y: i32) -> i32 {
    let sum = x + y;
    sum
}

fn main() {
    let a = 5;
    let b = 3;
    let result = add(a, b);
    println!("The sum is: {}", result);
}
در این برنامه‌ی Rust، دو عملکرد add و main را داریم. هنگامیکه برنامه شروع به اجرا می‌کند، یک stack frames برای تابع اصلی در حافظه‌ی پشته ایجاد می‌شود. این  stack frames شامل متغیرهای محلی a، b و فراخوانی تابع برای add(a, b) است.
هنگامیکه تابع add فراخوانی می‌شود، یک stack frames دیگر در بالای stack frames main موجود ایجاد می‌شود. این stack frames جدید حاوی متغیرهای محلی x، y و sum است. مقادیر a و b به عنوان آرگومان به تابع add ارسال می‌شوند و به ترتیب در x و y ذخیره می‌شوند. پس از محاسبه‌ی مجموع، تابع add، مقداری را بر می‌گرداند و  stack frames آن به طور خودکار از حافظه‌ی پشته حذف می‌شود.
سپس تابع main، مقدار برگشتی را از تابع add دریافت می‌کند و به نتیجه‌ی متغیر اختصاص می‌یابد. از ماکروی println! برای چاپ نتیجه استفاده می‌شود. پس از اتمام اجرای برنامه و بازگشت تابع اصلی، stack frames آن نیز از حافظه‌ی پشته حذف می‌شود و حافظه به‌طور خودکار پاک می‌شود.
در این مثال، می‌توانید ببینید که چگونه از stack frames برای ذخیره‌ی آرگومان‌های تابع و متغیرهای محلی در Rust استفاده می‌شود. اندازه‌ی این متغیرها در زمان کامپایل مشخص می‌شود و طول عمر حافظه‌ی پشته، برابر با طول عمر تابع است. هنگامیکه تابع برمی‌گردد، فرآیند پاکسازی آن خودکار است و قاب پشته‌ی مربوطه را حذف می‌کند.


Heap Memory

حافظه‌ی Heap، مقادیری را ذخیره می‌کند که باید فراتر از طول عمر یک تابع مانند مقادیر بزرگ و مقادیر قابل دسترسی توسط رشته‌های متعدد، زنده بمانند. از آنجائیکه هر رشته دارای پشته‌ی مخصوص به خود است، همه‌ی آنها یک پشته‌ی مشترک دارند. حافظه‌ی Heap می‌تواند مقادیری با اندازه‌ی ناشناخته را در زمان کامپایل، در خود جای دهد؛ مانند رشته‌های ورودی کاربر. اندازه‌ی پشته نیز پویا است؛ با حد بالایی ثابت که در زمان راه اندازی برنامه تعیین می‌شود. حافظه‌ی Heap طول عمری دارد که توسط برنامه نویس تعیین می‌شود و برنامه نویس تصمیم می‌گیرد که چه زمانی باید حافظه تخصیص داده شود. پاکسازی حافظه‌ی هیپ به صورت دستی است و نیاز به مداخله‌ی برنامه نویس دارد.
در این مثال ساده، روش استفاده از حافظه‌ی پشته نشان داده می‌شود:
use std::rc::Rc;

#[derive(Debug)]
struct LargeData {
    data: Vec<i32>,
}

impl LargeData {
    fn new(size: usize) -> LargeData {
        LargeData {
            data: vec![0; size],
        }
    }
}

fn main() {
    let large_data = Rc::new(LargeData::new(1_000_000));
    let shared_data1 = Rc::clone(&large_data);
    let shared_data2 = Rc::clone(&large_data);

    println!("{:?}", shared_data1);
    println!("{:?}", shared_data2);
}
در این برنامه‌ی Rust، یک ساختار LargeData را تعریف می‌کنیم که حاوی <Vec<i32 است. این روش جدید، یک شیء LargeData را به اندازه‌ی مشخصی مقداردهی اولیه می‌کند. در تابع main، یک شیء LargeData را با اندازه (1,000,000 عنصر) ایجاد می‌کنیم و با استفاده از Rc::new روی پشته ذخیره می‌کنیم. Rc یک اشاره‌گر شمارش مرجع است که به چندین متغیر اجازه می‌دهد تا مالکیت داده‌های تخصیص داده شده را به اشتراک بگذارند (در ادامه‌ی دوره توضیح داده خواهد شد).  
سپس دو متغیر دیگر را به نام‌های shared_data1 و shared_data2 ایجاد می‌کنیم که با استفاده از Rc::clone، یک شیء LargeData تخصیص‌یافته‌ی مشابه را به اشتراک می‌گذارند. این نشان می‌دهد که چگونه حافظه‌ی پشته را می‌توان در بین متغیرهای متعددی به اشتراک گذاشت؛ حتی فراتر از طول عمر تابع اصلی که داده را ایجاد کرده است.
در این مثال، پاکسازی حافظه‌ی پشته به طور خودکار توسط مکانیزم شمارش مرجع Rust مدیریت می‌شود (در ادامه‌ی دوره توضیح داده خواهد شد). هنگامیکه تعداد مرجع نشانگر Rc به صفر می‌رسد (یعنی وقتی همه‌ی متغیرهایی که داده‌ها را به اشتراک می‌گذارند از محدوده خارج می‌شوند)، حافظه‌ی تخصیص داده شده، روی پشته تخصیص داده می‌شود.
این مثال نشان می‌دهد که چگونه می‌توان از حافظه‌ی پشته برای ذخیره‌ی ساختارهای داده یا مقادیر بزرگی استفاده کرد که باید بیشتر از طول عمر یک تابع باشند و چگونه می‌توان حافظه‌ی پشته را بین چندین متغیر به اشتراک گذاشت.
مطالب
آموزش زبان Rust - قسمت 6 - Fuctions
توابع یکی از اجزای اساسی برنامه نویسی Rust هستند. آنها به شما این امکان را می‌دهند که یک بلوک کد را کپسوله کنید که می‌تواند بارها و بارها با ورودی‌های مختلفی فراخوانی شود. در اینجا یک مثال از یک تابع در Rust آمده‌است:
fn main() {
    println!("The sum of 2 and 3 is {}", sum(2, 3));
}

fn sum(a: i32, b: i32) -> i32 {
    a + b
}
در این مثال، تابعی را به نام sum تعریف می‌کنیم که دو آرگومان i32 را می‌گیرد و مجموع آنها را برمی گرداند. سپس تابع sum را با آرگومان‌های 2 و 3 فراخوانی می‌کنیم و نتیجه را با استفاده از println در کنسول چاپ می‌کنیم.

Function Declaration

توابع در Rust با استفاده از کلمه‌ی کلیدی fn و به دنبال آن نام تابع، پارامترها و نوع بازگشت (در صورت وجود) اعلام می‌شوند. در اینجا دستور کلی برای اعلان یک تابع در Rust آمده‌است:
fn function_name(parameter1: type1, parameter2: type2) -> return_type {
    // بدنه تابع
    // استفاده از مقادیر یارگشتی در صورت لزوم
}
در مثال بالا، تابع sum دو پارامتر، هر دو از نوع i32 را می‌گیرد و مقدار i32 را برمی گرداند.
 
Function Parameters
توابع در Rust می‌توانند صفر یا چند پارامتر را داشته باشند. پارامترها در امضای تابع، داخل پرانتز قرار گرفته و با کاما از هم جدا می‌شوند. در اینجا یک مثال، از یک تابع، با دو پارامتر آورده شده‌است:
fn greet(name: &str, age: i32) {
    println!("Hello, {}! You are {} years old.", name, age);
}
در این مثال، تابع greet دو پارامتر دارد: a &str (اشاره به یک رشته) و i32 (یک عدد صحیح). در داخل بدنه تابع، از مقادیر پارامترها برای چاپ پیام تبریک استفاده می‌کنیم.

Function Return Values
توابع در Rust می‌توانند با استفاده از کلمه‌ی کلیدی return و سپس مقدار بازگشتی، مقداری را برگردانند. یک مثال:
fn square(x: i32) -> i32 {
    return x * x;
}
در این مثال، تابع square، آرگومان i32 را می‌گیرد و square آن آرگومان را برمی‌گرداند. برای برگرداندن نتیجه، از کلمه کلیدی بازگشت استفاده می‌کنیم.
با این حال، Rust یک سینتکس مختصر را نیز برای برگرداندن مقادیر، از توابع دارد که در آن می‌توانید کلمه‌ی کلیدی return را حذف کنید و به سادگی مقداری را که باید در انتهای بدنه‌ی تابع برگردانده شود، مشخص کنید. در اینجا همان مثال، با استفاده از سینتکس کوتاه آمده‌است:
fn square(x: i32) -> i32 {
    x * x
}
در این مثال، کلمه‌ی کلیدی return را حذف کرده‌ایم و به‌سادگی مقداری را که باید به عنوان آخرین خط بدنه تابع برگردانده شود، مشخص کرده‌ایم.

Functions with Multiple Return Values
Rust همچنین از توابعی با مقادیر بازگشتی چندگانه پشتیبانی می‌کند که به آنها 'tuples' نیز می‌گویند. یک مثال:
fn swap(a: i32, b: i32) -> (i32, i32) {
    (b, a)
}
این تابع دو پارامتر i32 را می‌گیرد و یک tuple  از همان نوع را برمی‌گرداند. tuple، شامل دو مقدار ورودی مبادله شده‌است.
برای استفاده از مقادیر بازگشتی یک تابع tuple، می‌توانید tuple  را destructure کنید یا از عملگر '.' برای دسترسی به عناصر آن استفاده کنید. در این مثال هر دو روش وجود دارند: 
let (b, a) = swap(1, 2);
println!("a is {} and b is {}", a, b);

let tuple = swap(1, 2);
println!("a is {} and b is {}", tuple.1, tuple.0);
روش اول تاپل را مستقیماً به متغیرهای a و b تجزیه می‌کند؛ در حالیکه روش دوم با استفاده از عملگر نقطه، به داده‌ها دسترسی پیدا میکند.
مطالب
آموزش زبان Rust - قسمت 11 - Structs
Rust، زبان برنامه نویسی سیستمی است که برای ایمنی، همزمانی و عملکرد طراحی شده‌است و همین جهت به یک انتخاب محبوب برای توسعه‌ی نرم افزارهای مدرن تبدیل شده‌است. struct  یکی از بلوک‌های ساختمانی اساسی در Rust ساختار است که مخفف کلمه‌ی 'structure' است. ساختارها، انواع داده‌های سفارشی هستند که به توسعه دهندگان اجازه می‌دهند تا داده‌های مرتبط را به شیوه‌ای تمیز و کارآمد، با هم گروه بندی کنند. در این مقاله، قدرت و انعطاف‌پذیری سازه‌ها را در Rust، بررسی می‌کنیم و یاد می‌گیریم که چگونه، به‌طور مؤثری از آنها در پروژه‌های Rust خود استفاده کنیم. 

تعریف struct  
برای تعریف struct در Rust، از کلمه‌ی کلیدی struct استفاده کنید و به دنبال آن، نام ساختار و فیلدهای آن در براکت‌هایی باز و بسته محصور می‌شود. هر فیلد باید یک نام و یک نوع داشته باشد که با : از هم جدا شده‌اند. به عنوان مثال در اینجا یک ساختار ساده، نشان دهنده‌ی یک نقطه‌ی دو بعدی است:
struct Point {
    x: f64,
    y: f64,
}

نمونه مقدار دهی struct : 

let point = Point { x: 1.0, y: 2.0 };

دسترسی به فیلد‌های struct : 
برای دسترسی به فیلدهای یک struct ، از علامت نقطه استفاده کنید: 
let x = point.x;
let y = point.y;

نمونه های  struct   قابل تغییر 

برای ایجاد یک نمونه‌ی قابل تغییر از یک struct ، از کلمه‌ی کلیدی mut استفاده کنید که به شما امکان می‌دهد تا مقادیر فیلدها را تغییر دهید:  
let mut point = Point { x: 1.0, y: 2.0 };
point.x = 3.0;
point.y = 4.0;

Tuple Struct 

Rust همچنین از ساختارهای tuple نیز پشتیبانی می‌کند که ساختارهایی بدون نام فیلدها هستند. آنها زمانی مفید هستند که می‌خواهید یک ساختار را با تعداد کمی فیلد ایجاد کنید و نیازی به نامگذاری صریح آنها ندارید. برای تعریف ساختار tuple، از کلمه‌ی کلیدی struct و به دنبال آن، نام و انواع فیلدهای داخل پرانتز استفاده کنید:
struct Color(u8, u8, u8);
برای ایجاد یک نمونه از یک ساختار تاپل، از نام و مقادیر، داخل پرانتز استفاده کنید:
let red = Color(255, 0, 0);

Unit Struct

unit struct  یک struct بدون هیچ فیلدی است. برای تعریف ساختار واحد، از کلمه‌ی کلیدی struct و به دنبال آن نام و نقطه ویرگول استفاده کنید:
struct Jump;
struct Crouch;
struct Attack;

struct Character {
    name: String,
}

fn perform_action(character: &Character, action: &dyn Any) {
    if action.is::<Jump>() {
        println!("{} jumps!", character.name);
    } else if action.is::<Crouch>() {
        println!("{} crouches!", character.name);
    } else if action.is::<Attack>() {
        println!("{} attacks!", character.name);
    } else {
        println!("{} does nothing...", character.name);
    }
}

fn main() {
    let character = Character {
        name: "John Doe".to_string(),
    };

    perform_action(&character, &Jump);
    perform_action(&character, &Crouch);
    perform_action(&character, &Attack);
}

Structs in Rust روشی قدرتمند و انعطاف‌پذیر را برای تعریف انواع داده‌های سفارشی که داده‌های مرتبط را با هم گروه‌بندی می‌کنند، ارائه می‌کند. آنها با کپسوله کردن داده‌ها و عملکردهای مرتبط، به ایجاد کد تمیز و قابل نگهداری کمک می‌کنند. در این مقاله، ما اصول اولیه تعریف، نمونه سازی و دسترسی به ساختارها و همچنین موضوعات پیشرفته‌ای مانند ساختارهای tuple ، unit struct و را بررسی کردیم. با درک کاملی از ساختارها، می‌توانید پتانسیل کامل Rust را در پروژه‌های خود آزمایش کنید و نرم‌افزاری کارآمد و ایمن بسازید.