جستجو برای:
سبد خرید 0
  • صفحه اصلی
  • دوره‌های آموزشی
  • وبلاگ
  • درباره ما
  • قوانین و مقررات
  • همکاری با ما
  • تماس با ما
محتوای باز
ورود
[suncode_otp_login_form]
گذرواژه خود را فراموش کرده اید؟
عضویت
[suncode_otp_registration_form]
  • خانه
  • کتاب آنلاین
  • درباره سایت
  • درباره لوگو
  • تماس با ما
محتوای باز
  • صفحه اصلی
  • دوره‌های آموزشی
  • وبلاگ
  • درباره ما
  • قوانین و مقررات
  • همکاری با ما
  • تماس با ما
شروع کنید
آخرین اطلاعیه ها
لطفا برای نمایش اطلاعیه ها وارد شوید
0
[wcas-search-form]

آشنایی فنی با زبان اسکالا

19 مرداد 1400
ارسال شده توسط فرشید نوتاش حقیقت
برنامه‌نویسی

زبان اسکالا خلاصه‌گو است. تا جایی که ممکن باشد نیازی نیست مسائل قابل تشخیص را در این زبان بیان کرد. برای مثال هنگام معرفی یک متغیر نیازی نیست نوع آن نیز تعریف شود و کامپایلر سعی می‌‌‌‌‌کند از چیزی که به آن منتصب شده، نوع آن را تشخیص دهد.

برای مثال کد زیر در جاوا

final ArrayList names = new ArrayList();
names.add("name1");
names.add("name2");
names.add("name3");

و یا کد زیر در سی‌شارپ

var names = new List { "name1", "name2", "name3" }

به این شکل در اسکالا نوشته می‌‌‌‌‌شود

val names = List("name1", "name2", "name3")

در این مثال باید به این نکته توجه کرد که حتی در سی‌شارپ که خلاصه‌گو‌تر از جاواست باید حداقل مشخص کرد که لیستی حاوی نوع داده‌ای رشته (String) ایجاد می‌‌‌‌‌شود (اشاره به انواع Generic) در حالی که کامپایلر اسکالا این مورد را نیز تشخیص می‌‌‌‌‌دهد و نوعی که برای شناسه names مشخص می‌‌‌‌‌کند List [String] (لیستی از رشته) است.

مثلا اگر لیستی از اعداد صحیح مد نظر بود، کد بالا در اسکالا به این شکل نوشته می‌‌‌‌‌شد

val numbers = List(1, 2, 3)

نکته بسیار مهم این است که اسکالا بررسی زمان کامپایل نوع داده‌ها را فدای مختصر بودن نمی‌‌‌‌‌کند و بدون از دست دادن Type-safety حس کار با یک زبان پویا مثل روبی را به برنامه‌نویس می‌‌‌‌‌دهد. یکی از معدود مواردی که در آن اعلان نوع داده در اسکالا اجباری است، پارامتر‌های متد است.

برای مثال یک متد که یک عدد صحیح را از ورودی دریافت کرده و آن را چاپ می‌‌‌‌‌کند به شکل زیر نوشته می‌‌‌‌‌شود

def printnum(num: Int) = println(num.toString)

همان طور که ملاحضه می‌‌‌‌‌شود تعریف یک متد نیز به سادگی و با کم‌ترین میزان کد نویسی امکان‌پذیر است.

تعریف کلاس

قطعه کد زیر در جاوا یک کلاس به همراه یک سازنده و دو عضو را تعریف می‌‌‌‌‌کند

class MyClass { 
    private final String name; 
    private final int age; 

    public MyClass(String name, int age) { 
        this.name = name; 
        this.age = age; 
    }   
    public String getName() { return name; } 
    public String getAge() { return age; } 
}

قطعه کد زیر در اسکالا دقیقا معادل کد جاوا است

class MyClass(val name: String, val age: Int)

برنامه‌نویسی تابعی (Functional)

برنامه‌نویسی تابعی (Functional Programming) توسط بیشتر زبان‌های جدید پشتیبانی می‌‌‌‌‌شوند و پشتیبانی در زبان اسکالا کامل‌تر از زبان‌هایی مثل جاوا ۸ و سی‌شارپ است.

برای مثال با قطعه کد زیر می‌‌‌‌‌توان عملگر using سی‌شارپ را در اسکالا شبیه‌سازی کرد

trait Disposable { 
  def dispose() 
} 
def using[A <: Disposable, B](disposable: A)(block: A => B) = { 
  try { 
    block(disposable) 
  } finally { 
    disposable.dispose() 
  } 
}

و سپس به شکل زیر استفاده نمود

using (new MyDisposableClass()) { d =>   
  // ...
}

و البته بسیاری از متدهای پرکاربرد بر روی انواع داده‌های کلکسیونی (Collections) در اسکالا وجود دارند که یک نمونه از آن‌ها به شکل زیر است

val list = 1 to 100
list.filter(i => i % 2 == 0).map(i => println(i))
// The above code can be written like the following one
list.filter(_ % 2 == 0).map(println(_))
// And can be like this (using infix notation)
list filter (_ % 2 == 0) map println

در خط اول یک لیست از اعداد ۱ تا ۱۰۰ ساخته می‌‌‌‌‌شود و سپس در خط دوم از بین آن‌ها فقط اعداد زوج در خروجی چاپ می‌‌‌‌‌شوند. البته برای خلاصه‌گویی بیشتر کد خط دوم می‌‌‌‌‌تواند به شکل خط چهارم نوشته شود. و البته با استفاده از Infix notation می‌‌‌‌‌تواند به شکل خط ششم نوشته شود.

انواع داده‌ای قوی

از آن جایی که زبان اسکالا یک زبان با بررسی نوع داده‌ای زمان کامپایل است (Type-safe)، وجود سیستم انواع داده‌ای قوی و منعطف از الزامات آن است که خوشبختانه کتابخانه استاندارد اسکالا در این زمینه بسیار قوی عمل کرده است.

برای مثال نوع داده‌ای Option قابل بررسی است. این نوع داده تقریبا معادل نوع Nullable در سی‌شارپ است اما با ویژگی‌ها و امکانات بیش‌تر.
این نوع دارای دو فرزند به نام‌های Some و None است. همان طور که از نام‌ها پیداست، زمانی که وجود یا عدم وجود یک داده امکان‌پذیر باشد از این نوع داده استفاده می‌‌‌‌‌شود. برای مثال وقتی یک متد قرار است یک کاربر را بر اساس شناسه آن جستجو کند، اگر کاربری یافت نشود به جای برگرداندن مقدار Null یا ایجاد Exception، می‌‌‌‌‌توان مقدار None را برگرداند. در برنامه‌نویسی همروند ایجاد Exception مشکلات زیادی ایجاد می‌‌‌‌‌کند و استفاده از Null هم به نحو دیگری مشکل‌زا و غلط است.

چنین متدی به شکل زیر تعریف می‌‌‌‌‌شود

def getUserById(id: Int): Option[User] = {
  if (/* There was a user with the specified ID*/) {
    Some(foundUser)
  } else {
    None
  }
}

بدون شک با استفاده از نوع داده‌ای Option احتمال روبرو شدن با خطای NullReferenceException به صفر می‌‌‌‌‌رسد. برای نمونه، نویسنده این مقاله بعد از حدود یکسال کار بر روی زبان اسکالا و تولید نرم‌افزارهای مختلف، حتی یک بار هم به خطای NullRefrence برخورد نکرده است.

تطبیق الگو (Pattern Matching)

نوع داده‌ای Option که در بخش قبل مطرح شد به راحتی در هر زبان دیگر نیز قابل پیاده‌سازی است. اما یکی از دلایلی که باعث می‌‌‌‌‌شود یک برنامه‌نویس اسکالا هر روز از امثال این نوع داده‌ در کدهایش استفاده کند امکان Pattern Matching است.

فرض کنیم نوع Option در سی‌شارپ وجود داشت. می‌‌‌‌‌خواهیم برنامه‌ای بنویسیم که ابتدا متد getUserById را صدا زده و در صورت وجود کاربر، اگر نام کاربر با حرف «a» شروع می‌‌‌‌‌شد، جمله «Starts with A» را در خروجی چاپ کند، در غیر این صورت جلمه «Doesn’t start with A» و در صورتی که کاربر وجود نداشت جمله «Nothing to say» را چاپ کند. برنامه در سی‌شارپ به شکل زیر خواهد بود

var maybeUser = getUserById(userId); 
var user = maybeUser as Some[User]; 
if (user != null) { 
    if (user.name.startsWith("a")) { 
        Console.WriteLine("Starts with A"); 
    } else { 
        Console.WriteLine("Doesn't start with A"); 
    } 
} else { 
    Console.WriteLine("Nothing to say"); 
}

اما همین قطعه کد در اسکالا با استفاده از Pattern Matching به شکل زیر خواهد بود

getUserById(userId) match { 
    case Some(user) if user.name.startsWith("a") => println("Starts with A"); 
    case Some(user) => println("Doesn't starts with A"); 
    case None => println("Nothing to say"); 
}

این یک مثال بسیار ساده است. می‌‌‌‌‌توان تصور کرد در شرایط پیچیده‌تر وجود Pattern Matching چقدر مفید خواهد بود.

ماکروها (Macros)

ماکرو‌ها در اسکالا امکان تغییر ساختار کدهای برنامه قبل از کامپایل برنامه را می‌‌‌‌‌دهند.

برای مثال کد زیر در چارچوب پلی (Play)1 برای تبدیل یک رشته JSON به یک شی استفاده می‌‌‌‌‌شود

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
case class Person(name: String, age: Int, lovesChocolate: Boolean) 
implicit val personReads = ( 
  (__ \ 'name).read[String] and 
  (__ \ 'age).read[Int] and 
  (__ \ 'lovesChocolate).read[Boolean] 
)(Person)

هر چند این قطعه کد به نظر زیاده‌گو می‌‌‌‌‌آید ولی برای تبدیل JSON به یک شی نه از Reflection استفاده می‌‌‌‌‌شود و نه از هیچ یک از روش‌های پویا. به این ترتیب این کد یکی از سریع‌ترین کدها برای تبدیل JSON است بدون این‌که نیاز به راه‌اندازی و از این قبیل داشته باشد و همه این‌ها به دلیل Hard-code بودن قطعه کد اصلی یعنی پنج خط آخر است.

اما مهم‌ترین ضعف آن، زیاده‌گویی است که برای برنامه‌نویسان امروزی قابل قبول نیست. یکی از راه‌حل‌های جالب موجود در اسکالا استفاده از ماکرو‌ است. چارچوب پلی ماکرویی برای ایجاد این قطعه کد در زمان کامپایل ایجاد کرده تا قطعه کد بالا به شکل زیر در آید

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
case class Person(name: String, age: Int, lovesChocolate: Boolean) 
implicit val personReads = Json.reads[Person]

این قطعه کد نه از Reflection استفاده می‌‌‌‌‌کند و نه Type-safety را از بین می‌‌‌‌‌برد و دقیقا همان قطعه کد بالا را تولید می‌‌‌‌‌کند ولی مختصر و مفید است!

جمع‌بندی

موارد یاد شده بخشی از ویژگی‌های زبان اسکالا است ولی جزییات فراوانی برای بررسی وجود دارد که در این مقاله نمی‌‌‌‌‌گنجد. خوشبختانه منابع قابل قبولی برای یادگیری و بررسی زبان و اکو سیستم اسکالا وجود دارد.

امید است این مقاله هیجان و انرژی لازم برای دنبال کردن آن‌ها را ایجاد کرده باشد.

منبع: نشریه «سلام دنیا»، شماره دوم – نوشته امیر کریمی
برچسب ها: Scalaاسکالا
درباره فرشید نوتاش حقیقت

همیشه نیازمند یک منبع آموزشی فارسی در حوزه نرم‌افزارهای آزاد/ متن‌باز و سیستم‌عامل گنو/لینوکس بودم. از این رو این رسالت رو برای خودم تعریف کردم تا رسانه «محتوای باز» رو بوجود بیارم.

نوشته‌های بیشتر از فرشید نوتاش حقیقت
قبلی زبان برنامه‌نویسی Scala
بعدی چگونه در گیت‌هاب، وب‌سایت‌ بسازیم (قسمت اول)

دیدگاهتان را بنویسید لغو پاسخ

این سایت از اکیسمت برای کاهش جفنگ استفاده می‌کند. درباره چگونگی پردازش داده‌های دیدگاه خود بیشتر بدانید.

جستجو
جستجو برای:
دسته‌بندی موضوعی مقالات
  • برنامه‌نویسی
    • پایتون
    • دواپس
  • پایگاه‌داده
    • MariaDB
    • MySQL
  • تجارت الکترونیک
    • بازاریابی اینترنتی
    • دیجیتال مارکتینگ
    • شبکه‌های اجتماعی
  • جامعه کاربری
    • لاگ
  • دسته‌بندی نشده
  • شبکه و امنیت
  • طراحی وب
    • سئو
    • سیستم مدیریت محتوا
      • وردپرس
  • فناوری‌های نوظهور
    • اینترنت اشیاء
    • رایانش ابری
      • OpenStack
    • کلان‌داده‌ها
  • گنو/لینوکس
    • توزیع
      • CentOS
      • اوبونتو
      • دبیان
      • فدورا
    • چیست
    • خط فرمان
  • مهاجرت به آزاد/متن‌باز
  • نرم‌افزار
    • اداری
      • لیبره آفیس
        • ایمپرس
        • بیس
        • دراو
        • رایتر
        • کالک
    • کاربردی
    • گرافیک و انیمیشن
      • بلندر
      • گیمپ
نماد الکترونیکی (اینماد)
پرداخت‌یار

محتوای باز؛ مرجع آموزشی نرم‌افزارهای آزاد/ متن‌باز

از اینکه قصد همکاری با رسانه «محتوای باز» را دارید بسیار خرسندیم و این مایه مباهات ماست.

نحوه همکاری با ما چندان پیچیده نیست و شرایط آن در ادامه، ارائه گردیده است.

دستمزد مدرسین

پیش از بیان شرایط ضبط ویدئو شایان ذکر است اشاره‌ای به دستمزد مدرسین سایت داشته باشیم.

شما ممکن است در دو حالت تمایل به نشر ویدئو خود را داشته باشید: یا آن را رایگان در اختیار عموم قرار دهید و یا اینکه در قبال فروش آن از خریدار وجه مربوطه محصول را اخذ نمایید.

صرف نظر از هر حالت ممکنه، می‌بایست شرایطی که در ادامه ذکر شده‌اند را رعایت کرده باشید.

در حالت اول (رایگان) رسانه محتوای باز (Open Content)، نه وجهی از شما برای نشر ویدئو می‌گیرد و نه وجهی به شما پرداخت می‌نماید و دوره آموزشی شما را به رایگان منتشر می‌کند.

اما در حالت بعدی طریقه همکاری به روش درآمد از فروش خواهد بود، به گونه‌ای که 70 درصد از کل مبلغ فروش دوره آموزشی متعلق به مدرس دوره بوده و 30 درصد مابقی به رسانه محتوای باز تعلق می‌گیرد.

شرایط کلی ضبط دوره آموزشی

دوره آموزشی مربوطه، صرف نظر از هر محتوایی که دارد می‌بایست در یکی از توزیعات گنو/لینوکسی ضبط شده باشد. (به‌عنوان مثال دوره دروپال در اوبونتو، دوره آموزشی کار با آردوینو در دبیان و امثالهم). اگر دوره آموزشی شما در محیط ویندوز و یا هر پلتفرم/سیستم‌عامل دیگری ضبط شده باشد از همکاری با شما معذوریم.

پیشنهاد می‌گردد برای ضبط دوره آموزشی در توزیع گنو/لینوکس از ابزار قدرتمند OBS استفاده نمایید. البته این صرفا یک پیشنهاد است و شما می‌توانید از هر ابزار مناسب دیگری برای این کار بهره ببرید.

برای آشنایی یا تسلط بیشتر می‌توانید دوره رایگان آموزش OBS محمد عابدینی را ببینید:

مشاهده دوره آموزش OBS
شرایط کیفی ضبط دوره آموزشی

کیفیت صدا از اهمیت ویژه‌ای برخوردار می‌باشد و می‌بایست فاقد هر گونه نویز یا صدای اضافی دیگری (صدای محیط پیرامون) باشد.

دوره آموزشی تهیه شده صرفا باید برای رسانه محتوای باز تدوین شده باشد و در هیچ سایت مشابه دیگری قرار نگرفته باشد.

از قرار دادن موسیقی متن، در بک‌گراند دوره آموزشی شدیدا پرهیز کنید. این کار موجب حواس‌پرتی مخاطب و ضعیف شدن صدای مدرس می‌گردد.

دوره آموزشی ضبط شده می‌باید فاقد هر گونه لوگو یا آدرس سایت دیگری (در گوشه تصویر یا بک‌گراند صفحه دسکتاپ و هر جای دیگری) باشد.

در حین دوره، مدرس نباید به برند خاصی اشاره کند که جز رقبای ما به‌شمار می‌آیند.

مدرس باید در ابتدا در اواسط و در انتهای دوره به برند ما یعنی رسانه محتوای باز (Open Content) بصورت کلامی اشاره نماید.

مدرس، هنگام تدریس نباید تپق زده، سرفه یا عطسه کند یا صدای قورت دادن بزاقش شنیده شود و بایستی با صدای رسا، دوستانه و پرانرژی به تدریس بپردازد.

قبل از تدوین دوره آموزشی حتما با ما در تماس باشید و یک ویدیوی چنددقیقه‌ای (ترجیحا 5 الی 10 دقیقه)، بصورت نمونه‌کار برای ما بفرستید.

از همکاری با شما سپاسگزاریم.

فراخوان همکاری