ما در سی شارپ متغیر داریم که ممکن هر لحظه تغییر کنند.متغیر ها ذاتا mutable (تغییر پذیر) هستند (البته می توانید متغیر تغییر ناپذیر-immutable- نیز تعریف کنیم). اما در F# بطور پیش فرض مقادیر immutable - تغییر ناپذیر- داریم که به هیچ وجه مقدار آنها تغییر نمی کند - پس بجای واژه متغیر از واژه مقدار یا مقادیر استفاده می کنیم. (همچنین در F# نیز می توانیم متغییر یا mutable نیز تعریف کنیم.)
در حالت عادی برنامه های f# با یک فایل .fs شروع میشوند ، که کدها درون آن قرار می گیرند. برای جلوگیری از پیچیدگی و بزرگ شدن بیش از حد باید از Module ها استفاده کنیم.
دو نوع ماژول داریم
1- سطح بالا TopLevel-Module
2- محلی Local-Module
ماژول سطح بالا کل فایل بر می گرداند
ماژول محلی بخشی از یک فایل را بر می گرداند. محل تعریف ماژول محلی همیشه بخشی از یک ماژول سطح بالا یا یک namespace می باشد.
یک فایل .fs با نام File1 ایجاد کنید.
تعریف یک ماژول سطح بالا:
module File1Module Code Here ...
تعریف یک ماژول محلی:
module File1Module Code Here ... module Moudel1 = Code Here ...
(به تو رفتگی دقت کنید)
نکته: می توانیم ماژول های تو در توی محلی نیز تعریف کنیم
module File1Module let value = 123 let x = File2Module.value module Module1 = let Module1Value = value + File2Module.Module1.Module1Value module Module2 = let Module2Value = Module1.Module1Value module NestedModule1 = let NestedModule1Value = x * 2
(به تو رفتگی ها دقت کنید)
استفاده از نام کامل ماژول :
استفاده از عملگر Open :
از فایل ها در Solution از بالا به پایین compile می شوند. فایلی که در بالاترین سطح فایل ها قرار می گیرد از محتوای فایل های زیرین خود اطلاعی ندارد (چون هنوز فایل های زیرین compile نشدنند!) پس ترتیب فایل ها در Solution مهم است در غیر این صورت با خطا مواجه می شوید.
در تصویر بالا File2 هیچ وابستگی به فایل های دیگر ندارد. File1 به File2 وابسته است (مثلا ماژول محلی ای از آن فایل را می خواند) اما به فایل Program وابسته نیست. و اما فایل Program که فایل اصلی هست و همیشه در آخر می باشد. که از هردو (نه الزاما) فایل قبلی استفاده میکند (مثلا ماژول سطح بالای File1 استفاده می کند.)
مانند using در سی شارپ عمل می کند برای جلوگیری از نوشتن نام کامل ماژول (اگر با یک ماژول زیاد سروکار دارید بهتر است از Open استفاده کنید). با نگاه داشتن نشانه گر موس روی مقادیر نام کامل آن نمایش داده خواهد شد.
اما ممکن هست در استفاده از Open عمل shadowing (پنهان سازی رخ دهد) اگر، به نام مقدار های دو عمل گر Open یکسان باشند. به عنوان مثال:
همانطور که می بینید دو ماژول را Open کردیم که هر دو مقداری با نام مشابه دارند (Modul1Value). کامپایلر مشکلی با نام های یکسان ندارد پس خطای کامپایلری رخ نمی دهد. مشکل از اینجا شروع می شود که مقدار (Modul1Value) بر اساس آخرین open مقداردهی می شود(همانطور که در عکس هم قابل مشاهده است ویژوال استودیو open اول را به نشانه بی اثر بودن کم رنگ کرده است).
برای جلوگیری کردن از این مشکل باید کاری کنیم که ماژول با نام کامل نوشته شود (نتوان آن را open کرد) برای این کار کافیست بر چسب زیر را به ماژول:
[<RequireQualifiedAccess>]
که به معنای "اجبار به دسترسی توصیف شده" با این کار دسترسی به اعضای داخلی ماژول فقط از طریق نام آن ماژول انجام شود در غیر این صورت خطای کامپایلری می دهد. نحوه اعمال برچسب نیز در عکس وجود دارد (به [<EntryPoint>] دقت کنید).
فضای نام ها نیز مانند ماژول ها برای سازماندهی کردن کدها کاربرد دارند با این تفاوت که بطور مستقیم قابلیت نگهداری توابع و مقادیر را ندارند. برای ایجاد فضای نام باید از کلمه کلیدی namespace استفاده کرد. هر فایل می تواند شامل تعداد دلخواه فضای نام باشد.
استفاده (تعریف) فضای نام:
استفاده (تعریف) فضای نام تو در تو:
نکته: در برنامه هایی که از چندین فایل استفاده شود ، هر فایل باید از یک ماژول یا فضای نام شروع شود.