Ty

Typespecs در Elixir

1 تمرین

درباره‌ی Typespecs

Elixir یک زبان با نوع‌پذیری پویا است، یعنی بررسی نوع در زمان کامپایل انجام نمی‌شود. با این حال، مشخصات نوع می‌توانند مفید باشند، چون:

  • به عنوان مستندات عمل می‌کنند.
  • ابزارهای تحلیل ایستا مانند Dialyzer می‌توانند از آن‌ها برای یافتن خطاهای احتمالی استفاده کنند.

می‌توان مشخصات نوع را با استفاده از ویژگی ماژول @spec، درست پیش از تعریف تابع، به یک تابع افزود.

@spec longer_than?(String.t(), non_neg_integer()) :: boolean()
def longer_than?(string, length), do: String.length(string) > length

نوع

عبارت‌های مجاز در مشخصات نوع:

  • نوع‌های پایه، برای مثال:

    • boolean()
    • integer()، non_neg_integer()، pos_integer()، float()
    • list()
    • map()
    • any()
  • اجتماع چند نوع:

    • مثلاً integer() | list(integer())
  • نوع‌های پارامتردار:

    • مثلاً list(integer())، فهرستی از اعداد صحیح
    • مثلاً %{age: integer()}، یک map با یک مقدار صحیح زیر کلید :age
  • نوع‌های بیرونی (تعریف‌شده در یک ماژول)، برای مثال:

  • لیترال‌ها، برای مثال:

    • %{}، یک map خالی
    • []، یک فهرست خالی (اما [any()] یک فهرست ناتهی است)
    • مثلاً :ok، یک لیترال اتم
  • نوع‌های تخصصی توکار، برای مثال:

    • char()، یک عدد صحیح در بازه‌ی 0..0x10FFFF
    • charlist()، یک فهرست از کاراکترها
    • keyword()، یک فهرست از تاپل‌های دوعنصری که عنصر اولشان یک اتم است
  • نوع‌های سفارشی

فهرست کامل همه‌ی نوع‌ها را می‌توانید در بخش «Typespecs» در مستندات رسمی پیدا کنید.

نام‌گذاری آرگومان‌ها

آرگومان‌ها در مشخصات نوع را می‌توان نام‌گذاری کرد که برای تشخیص چند آرگومان هم‌نوع مفید است.

@spec to_hex({hue :: integer, saturation :: integer, lightness :: integer}) :: String.t()

نوع‌های سفارشی

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

  • @type، یک نوع عمومی تعریف می‌کند
  • @typep، یک نوع خصوصی تعریف می‌کند
  • @opaque، یک نوع عمومی تعریف می‌کند که ساختارش خصوصی است
@type color :: {hue :: integer, saturation :: integer, lightness :: integer}

@spec to_hex(color()) :: String.t()

String.t() در مقابل binary() در مقابل string()

String.t() نوع درست برای رشته‌های Elixir است، که باینری‌های کدگذاری‌شده با UTF-8 هستند. از نظر فنی، String.t() به‌صورت یک binary() تعریف شده و این دو نوع برای ابزارهای تحلیل معادل‌اند، اما String.t() انتخاب گویاتری برای مستندسازی توابعی است که با رشته‌های Elixir کار می‌کنند.

از سوی دیگر، string() نوع متفاوتی است. این یک رشته‌ی Erlang است که در Elixir به آن «charlist» می‌گویند. باید از نوع string() در مشخصات نوع پرهیز کرد و به‌جایش از charlist() استفاده کرد.

Dialyzer

Dialyzer یک ابزار تحلیل ایستا است که می‌تواند مشکلاتی مانند خطاهای نوع را در کد Erlang و Elixir تشخیص دهد. ساده‌ترین راه استفاده از Dialyzer در یک پروژه‌ی Elixir، استفاده از Dialyxir است.

ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

Typespecs را یاد بگیرید