মডিউল ট্রিতে একটি আইটেমকে রেফার করার জন্য পাথ (Paths for Referring to an Item in the Module Tree)

একটি মডিউল ট্রিতে একটি আইটেম কোথায় খুঁজতে হবে তা Rust-কে দেখানোর জন্য, আমরা ফাইল সিস্টেমে নেভিগেট করার সময় যেভাবে পাথ ব্যবহার করি সেভাবেই একটি পাথ ব্যবহার করি। একটি ফাংশন কল করার জন্য, আমাদের এর পাথ জানতে হবে।

একটি পাথ দুটি রূপ নিতে পারে:

  • একটি অ্যাবসোলিউট পাথ (absolute path) হল একটি ক্রেট রুট থেকে শুরু হওয়া সম্পূর্ণ পাথ; এক্সটার্নাল ক্রেটের কোডের জন্য, অ্যাবসোলিউট পাথ ক্রেটের নাম দিয়ে শুরু হয় এবং বর্তমান ক্রেটের কোডের জন্য, এটি লিটারেল crate দিয়ে শুরু হয়।
  • একটি রিলেটিভ পাথ (relative path) বর্তমান মডিউল থেকে শুরু হয় এবং self, super, বা বর্তমান মডিউলের একটি আইডেন্টিফায়ার ব্যবহার করে।

অ্যাবসোলিউট এবং রিলেটিভ উভয় পাথই ডাবল কোলন (::) দ্বারা পৃথক করা এক বা একাধিক আইডেন্টিফায়ার অনুসরণ করে।

Listing 7-1-এ ফিরে গিয়ে, ধরা যাক আমরা add_to_waitlist ফাংশনটি কল করতে চাই। এটি একই প্রশ্ন: add_to_waitlist ফাংশনের পাথ কী? Listing 7-3-তে Listing 7-1-এর কিছু মডিউল এবং ফাংশন সরিয়ে দেওয়া হয়েছে।

আমরা ক্রেট রুটে সংজ্ঞায়িত একটি নতুন ফাংশন, eat_at_restaurant থেকে add_to_waitlist ফাংশনটিকে কল করার দুটি উপায় দেখাব। এই পাথগুলো সঠিক, কিন্তু অন্য একটি সমস্যা রয়েছে যা এই উদাহরণটিকে কম্পাইল হতে বাধা দেবে। আমরা একটু পরেই এর কারণ ব্যাখ্যা করব।

eat_at_restaurant ফাংশনটি আমাদের লাইব্রেরি ক্রেটের পাবলিক API-এর অংশ, তাই আমরা এটিকে pub কীওয়ার্ড দিয়ে চিহ্নিত করি। pub কীওয়ার্ড দিয়ে পাথ এক্সপোজ করা” বিভাগে, আমরা pub সম্পর্কে আরও বিস্তারিত আলোচনা করব।

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

প্রথমবার যখন আমরা eat_at_restaurant-এ add_to_waitlist ফাংশনটি কল করি, তখন আমরা একটি অ্যাবসোলিউট পাথ ব্যবহার করি। add_to_waitlist ফাংশনটি eat_at_restaurant-এর মতোই একই ক্রেটে সংজ্ঞায়িত করা হয়েছে, যার মানে হল আমরা একটি অ্যাবসোলিউট পাথ শুরু করতে crate কীওয়ার্ড ব্যবহার করতে পারি। তারপর আমরা add_to_waitlist-এ পৌঁছানো পর্যন্ত ক্রমাগত প্রতিটি মডিউল অন্তর্ভুক্ত করি। আপনি একই কাঠামোর একটি ফাইল সিস্টেম কল্পনা করতে পারেন: add_to_waitlist প্রোগ্রামটি চালানোর জন্য আমরা /front_of_house/hosting/add_to_waitlist পাথটি নির্দিষ্ট করব; ক্রেট রুট থেকে শুরু করার জন্য crate নামটি ব্যবহার করা আপনার শেলে ফাইল সিস্টেম রুট থেকে শুরু করার জন্য / ব্যবহার করার মতো।

দ্বিতীয়বার যখন আমরা eat_at_restaurant-এ add_to_waitlist কল করি, তখন আমরা একটি রিলেটিভ পাথ ব্যবহার করি। পাথটি front_of_house দিয়ে শুরু হয়, যে মডিউলটির নাম eat_at_restaurant-এর মতোই মডিউল ট্রির একই স্তরে সংজ্ঞায়িত করা হয়েছে। এখানে ফাইল সিস্টেমের সমতুল্য হবে front_of_house/hosting/add_to_waitlist পাথ ব্যবহার করা। একটি মডিউলের নাম দিয়ে শুরু করার অর্থ হল পাথটি রিলেটিভ।

রিলেটিভ বা অ্যাবসোলিউট পাথ ব্যবহার করবেন কিনা তা বেছে নেওয়া আপনার প্রোজেক্টের উপর ভিত্তি করে একটি সিদ্ধান্ত, এবং এটি নির্ভর করে আপনি আইটেম সংজ্ঞার কোডটি আইটেমটি ব্যবহার করা কোড থেকে আলাদাভাবে নাকি একসাথে সরানোর সম্ভাবনা বেশি কিনা। উদাহরণস্বরূপ, যদি আমরা front_of_house মডিউল এবং eat_at_restaurant ফাংশনটিকে customer_experience নামক একটি মডিউলে সরিয়ে নিই, তাহলে আমাদের add_to_waitlist-এর অ্যাবসোলিউট পাথ আপডেট করতে হবে, কিন্তু রিলেটিভ পাথটি এখনও বৈধ থাকবে। যাইহোক, যদি আমরা eat_at_restaurant ফাংশনটিকে আলাদাভাবে dining নামক একটি মডিউলে সরিয়ে নিই, তাহলে add_to_waitlist কলের অ্যাবসোলিউট পাথ একই থাকবে, কিন্তু রিলেটিভ পাথটি আপডেট করতে হবে। সাধারণভাবে আমাদের পছন্দ হল অ্যাবসোলিউট পাথগুলো নির্দিষ্ট করা কারণ আমরা কোড সংজ্ঞা এবং আইটেম কলগুলো একে অপরের থেকে স্বাধীনভাবে সরাতে চাইতে পারি।

আসুন Listing 7-3 কম্পাইল করার চেষ্টা করি এবং জেনে নিই কেন এটি এখনও কম্পাইল হবে না! আমরা যে এররগুলো পাই সেগুলো Listing 7-4-এ দেখানো হয়েছে।

$ cargo build
   Compiling restaurant v0.1.0 (file:///projects/restaurant)
error[E0603]: module `hosting` is private
 --> src/lib.rs:9:28
  |
9 |     crate::front_of_house::hosting::add_to_waitlist();
  |                            ^^^^^^^  --------------- function `add_to_waitlist` is not publicly re-exported
  |                            |
  |                            private module
  |
note: the module `hosting` is defined here
 --> src/lib.rs:2:5
  |
2 |     mod hosting {
  |     ^^^^^^^^^^^

error[E0603]: module `hosting` is private
  --> src/lib.rs:12:21
   |
12 |     front_of_house::hosting::add_to_waitlist();
   |                     ^^^^^^^  --------------- function `add_to_waitlist` is not publicly re-exported
   |                     |
   |                     private module
   |
note: the module `hosting` is defined here
  --> src/lib.rs:2:5
   |
2  |     mod hosting {
   |     ^^^^^^^^^^^

For more information about this error, try `rustc --explain E0603`.
error: could not compile `restaurant` (lib) due to 2 previous errors

এরর মেসেজগুলো বলে যে hosting মডিউলটি প্রাইভেট। অন্য কথায়, আমাদের কাছে hosting মডিউল এবং add_to_waitlist ফাংশনের জন্য সঠিক পাথ রয়েছে, কিন্তু Rust আমাদের সেগুলো ব্যবহার করতে দেবে না কারণ এটির প্রাইভেট বিভাগে অ্যাক্সেস নেই। Rust-এ, সমস্ত আইটেম (ফাংশন, মেথড, স্ট্রাকট, এনাম, মডিউল এবং কনস্ট্যান্ট) ডিফল্টরূপে প্যারেন্ট মডিউলগুলোর কাছে প্রাইভেট। আপনি যদি একটি ফাংশন বা স্ট্রাকটের মতো একটি আইটেমকে প্রাইভেট করতে চান তবে আপনি এটিকে একটি মডিউলে রাখবেন।

প্যারেন্ট মডিউলের আইটেমগুলো চাইল্ড মডিউলের ভেতরের প্রাইভেট আইটেমগুলো ব্যবহার করতে পারে না, তবে চাইল্ড মডিউলের আইটেমগুলো তাদের পূর্বপুরুষ মডিউলগুলোর আইটেমগুলো ব্যবহার করতে পারে। এর কারণ হল চাইল্ড মডিউলগুলো তাদের ইমপ্লিমেন্টেশনের বিবরণ র‍্যাপ করে এবং লুকিয়ে রাখে, কিন্তু চাইল্ড মডিউলগুলো সেই প্রেক্ষাপটটি দেখতে পারে যেখানে সেগুলো সংজ্ঞায়িত করা হয়েছে। আমাদের রূপকটি চালিয়ে যেতে, গোপনীয়তার নিয়মগুলোকে একটি রেস্তোরাঁর ব্যাক অফিসের মতো ভাবুন: সেখানে যা ঘটে তা রেস্তোরাঁর গ্রাহকদের কাছে প্রাইভেট, কিন্তু অফিসের ম্যানেজাররা তারা যে রেস্তোরাঁটি পরিচালনা করেন তার সবকিছু দেখতে এবং করতে পারেন।

Rust মডিউল সিস্টেমটিকে এমনভাবে কাজ করার জন্য বেছে নিয়েছে যাতে অভ্যন্তরীণ ইমপ্লিমেন্টেশনের বিবরণ লুকানো ডিফল্ট হয়। এইভাবে, আপনি জানেন যে আপনি বাইরের কোড না ভেঙে ভিতরের কোডের কোন অংশগুলো পরিবর্তন করতে পারেন। যাইহোক, Rust আপনাকে একটি আইটেমকে পাবলিক করতে pub কীওয়ার্ড ব্যবহার করে চাইল্ড মডিউলের কোডের ভেতরের অংশগুলো বাইরের পূর্বপুরুষ মডিউলগুলোতে প্রকাশ করার অপশন দেয়।

pub কীওয়ার্ড দিয়ে পাথ এক্সপোজ করা (Exposing Paths with the pub Keyword)

আসুন Listing 7-4-এর এররটিতে ফিরে যাই যা আমাদের বলেছিল যে hosting মডিউলটি প্রাইভেট। আমরা চাই প্যারেন্ট মডিউলের eat_at_restaurant ফাংশনটির চাইল্ড মডিউলের add_to_waitlist ফাংশনে অ্যাক্সেস থাকুক, তাই আমরা hosting মডিউলটিকে pub কীওয়ার্ড দিয়ে চিহ্নিত করি, যেমনটি Listing 7-5-এ দেখানো হয়েছে।

mod front_of_house {
    pub mod hosting {
        fn add_to_waitlist() {}
    }
}

// -- snip --
pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

দুর্ভাগ্যবশত, Listing 7-5-এর কোডটি এখনও কম্পাইলার এরর দেয়, যেমনটি Listing 7-6-এ দেখানো হয়েছে।

$ cargo build
   Compiling restaurant v0.1.0 (file:///projects/restaurant)
error[E0603]: function `add_to_waitlist` is private
  --> src/lib.rs:10:37
   |
10 |     crate::front_of_house::hosting::add_to_waitlist();
   |                                     ^^^^^^^^^^^^^^^ private function
   |
note: the function `add_to_waitlist` is defined here
  --> src/lib.rs:3:9
   |
3  |         fn add_to_waitlist() {}
   |         ^^^^^^^^^^^^^^^^^^^^

error[E0603]: function `add_to_waitlist` is private
  --> src/lib.rs:13:30
   |
13 |     front_of_house::hosting::add_to_waitlist();
   |                              ^^^^^^^^^^^^^^^ private function
   |
note: the function `add_to_waitlist` is defined here
  --> src/lib.rs:3:9
   |
3  |         fn add_to_waitlist() {}
   |         ^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0603`.
error: could not compile `restaurant` (lib) due to 2 previous errors

কী ঘটল? mod hosting-এর সামনে pub কীওয়ার্ড যোগ করলে মডিউলটি পাবলিক হয়। এই পরিবর্তনের সাথে, যদি আমরা front_of_house অ্যাক্সেস করতে পারি, তাহলে আমরা hosting অ্যাক্সেস করতে পারব। কিন্তু hosting-এর কনটেন্টগুলো এখনও প্রাইভেট; মডিউলটিকে পাবলিক করা এর কনটেন্টগুলোকে পাবলিক করে না। একটি মডিউলে pub কীওয়ার্ড শুধুমাত্র তার পূর্বপুরুষ মডিউলগুলোর কোডকে এটি রেফার করার অনুমতি দেয়, এর ভেতরের কোড অ্যাক্সেস করতে নয়। যেহেতু মডিউলগুলো হল কন্টেইনার, তাই শুধুমাত্র মডিউলটিকে পাবলিক করে আমরা খুব বেশি কিছু করতে পারি না; আমাদের আরও এগিয়ে যেতে হবে এবং মডিউলের ভেতরের এক বা একাধিক আইটেমকেও পাবলিক করতে হবে।

Listing 7-6-এর এররগুলো বলে যে add_to_waitlist ফাংশনটি প্রাইভেট। গোপনীয়তার নিয়মগুলো স্ট্রাকট, এনাম, ফাংশন এবং মেথডের পাশাপাশি মডিউলগুলোর ক্ষেত্রেও প্রযোজ্য।

আসুন Listing 7-7-এর মতো add_to_waitlist ফাংশনটিকেও এর সংজ্ঞার আগে pub কীওয়ার্ড যোগ করে পাবলিক করি।

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

// -- snip --
pub fn eat_at_restaurant() {
    // Absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // Relative path
    front_of_house::hosting::add_to_waitlist();
}

এখন কোডটি কম্পাইল হবে! গোপনীয়তার নিয়মগুলোর সাপেক্ষে pub কীওয়ার্ড যোগ করলে কেন আমাদের eat_at_restaurant-এ এই পাথগুলো ব্যবহার করার অনুমতি দেয় তা দেখতে, আসুন অ্যাবসোলিউট এবং রিলেটিভ পাথগুলো দেখি।

অ্যাবসোলিউট পাথে, আমরা crate দিয়ে শুরু করি, আমাদের ক্রেটের মডিউল ট্রির রুট। front_of_house মডিউলটি ক্রেট রুটে সংজ্ঞায়িত করা হয়েছে। যদিও front_of_house পাবলিক নয়, কারণ eat_at_restaurant ফাংশনটি front_of_house-এর মতোই একই মডিউলে সংজ্ঞায়িত করা হয়েছে (অর্থাৎ, eat_at_restaurant এবং front_of_house হল সিবলিং), আমরা eat_at_restaurant থেকে front_of_house-কে রেফার করতে পারি। এরপর hosting মডিউলটি pub দিয়ে চিহ্নিত করা হয়েছে। আমরা hosting-এর প্যারেন্ট মডিউল অ্যাক্সেস করতে পারি, তাই আমরা hosting অ্যাক্সেস করতে পারি। অবশেষে, add_to_waitlist ফাংশনটি pub দিয়ে চিহ্নিত করা হয়েছে এবং আমরা এর প্যারেন্ট মডিউল অ্যাক্সেস করতে পারি, তাই এই ফাংশন কলটি কাজ করে!

রিলেটিভ পাথের ক্ষেত্রে, লজিকটি অ্যাবসোলিউট পাথের মতোই, প্রথম ধাপটি ছাড়া: ক্রেট রুট থেকে শুরু করার পরিবর্তে, পাথটি front_of_house থেকে শুরু হয়। front_of_house মডিউলটি eat_at_restaurant-এর মতোই একই মডিউলে সংজ্ঞায়িত করা হয়েছে, তাই eat_at_restaurant যে মডিউলে সংজ্ঞায়িত করা হয়েছে সেখান থেকে শুরু হওয়া রিলেটিভ পাথটি কাজ করে। তারপর, যেহেতু hosting এবং add_to_waitlist pub দিয়ে চিহ্নিত করা হয়েছে, তাই পাথের বাকি অংশটি কাজ করে এবং এই ফাংশন কলটি বৈধ!

যদি আপনি আপনার লাইব্রেরি ক্রেট শেয়ার করার পরিকল্পনা করেন যাতে অন্য প্রোজেক্টগুলো আপনার কোড ব্যবহার করতে পারে, তাহলে আপনার পাবলিক API হল আপনার ক্রেটের ব্যবহারকারীদের সাথে আপনার চুক্তি যা নির্ধারণ করে যে তারা কীভাবে আপনার কোডের সাথে ইন্টারঅ্যাক্ট করতে পারে। আপনার ক্রেটের উপর নির্ভর করা লোকেদের জন্য এটিকে সহজতর করার জন্য আপনার পাবলিক API-তে পরিবর্তনগুলো পরিচালনা করার বিষয়ে অনেক বিবেচনা রয়েছে। এই বিবেচনাগুলো এই বইয়ের সুযোগের বাইরে; আপনি যদি এই বিষয়ে আগ্রহী হন, তাহলে The Rust API Guidelines দেখুন।

বাইনারি এবং লাইব্রেরি সহ প্যাকেজগুলোর জন্য সর্বোত্তম অনুশীলন (Best Practices for Packages with a Binary and a Library)

আমরা উল্লেখ করেছি যে একটি প্যাকেজে একটি src/main.rs বাইনারি ক্রেট রুট এবং সেইসাথে একটি src/lib.rs লাইব্রেরি ক্রেট রুট উভয়ই থাকতে পারে এবং উভয় ক্রেটের নাম ডিফল্টরূপে প্যাকেজের নামের মতো হবে। সাধারণত, লাইব্রেরি এবং বাইনারি ক্রেট উভয়ই ধারণকারী এই প্যাটার্নের প্যাকেজগুলোতে বাইনারি ক্রেটে শুধুমাত্র একটি এক্সিকিউটেবল শুরু করার জন্য যথেষ্ট কোড থাকবে যা লাইব্রেরি ক্রেটের মধ্যে কোড কল করে। এটি অন্য প্রোজেক্টগুলোকে প্যাকেজ যে কার্যকারিতা সরবরাহ করে তার বেশিরভাগ থেকে উপকৃত হতে দেয় কারণ লাইব্রেরি ক্রেটের কোড শেয়ার করা যেতে পারে।

মডিউল ট্রিটি src/lib.rs-এ সংজ্ঞায়িত করা উচিত। তারপর, যেকোনো পাবলিক আইটেম প্যাকেজের নাম দিয়ে পাথ শুরু করে বাইনারি ক্রেটে ব্যবহার করা যেতে পারে। বাইনারি ক্রেটটি লাইব্রেরি ক্রেটের একজন ব্যবহারকারী হয়ে ওঠে ঠিক যেমন একটি সম্পূর্ণ এক্সটার্নাল ক্রেট লাইব্রেরি ক্রেট ব্যবহার করবে: এটি শুধুমাত্র পাবলিক API ব্যবহার করতে পারে। এটি আপনাকে একটি ভাল API ডিজাইন করতে সহায়তা করে; আপনি কেবল লেখক নন, আপনি একজন ক্লায়েন্টও!

চ্যাপ্টার 12-এ, আমরা একটি কমান্ড লাইন প্রোগ্রাম দিয়ে এই সাংগঠনিক অনুশীলনটি প্রদর্শন করব যাতে একটি বাইনারি ক্রেট এবং একটি লাইব্রেরি ক্রেট উভয়ই থাকবে।

super দিয়ে রিলেটিভ পাথ শুরু করা (Starting Relative Paths with super)

আমরা super দিয়ে পাথের শুরুতে প্যারেন্ট মডিউল থেকে শুরু হওয়া রিলেটিভ পাথ তৈরি করতে পারি, কারেন্ট মডিউল বা ক্রেট রুট থেকে নয়। এটি ফাইল সিস্টেমের পাথ .. সিনট্যাক্স দিয়ে শুরু করার মতো। super ব্যবহার করা আমাদের এমন একটি আইটেমকে রেফার করতে দেয় যা আমরা জানি প্যারেন্ট মডিউলে রয়েছে, যা মডিউল ট্রিকে পুনরায় সাজানো সহজ করে তুলতে পারে যখন মডিউলটি প্যারেন্টের সাথে ঘনিষ্ঠভাবে সম্পর্কিত কিন্তু প্যারেন্টকে হয়তো কোনো একদিন মডিউল ট্রির অন্য কোথাও সরানো হতে পারে।

Listing 7-8-এর কোডটি বিবেচনা করুন যা এমন পরিস্থিতিকে মডেল করে যেখানে একজন শেফ একটি ভুল অর্ডার ঠিক করে এবং ব্যক্তিগতভাবে সেটি গ্রাহকের কাছে নিয়ে আসে। back_of_house মডিউলে সংজ্ঞায়িত fix_incorrect_order ফাংশনটি প্যারেন্ট মডিউলে সংজ্ঞায়িত deliver_order ফাংশনটিকে কল করে, super দিয়ে শুরু করে deliver_order-এর পাথ নির্দিষ্ট করে।

fn deliver_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::deliver_order();
    }

    fn cook_order() {}
}

fix_incorrect_order ফাংশনটি back_of_house মডিউলে রয়েছে, তাই আমরা super ব্যবহার করে back_of_house-এর প্যারেন্ট মডিউলে যেতে পারি, যা এই ক্ষেত্রে crate, অর্থাৎ রুট। সেখান থেকে, আমরা deliver_order খুঁজি এবং এটি খুঁজে পাই। সফল! আমরা মনে করি back_of_house মডিউল এবং deliver_order ফাংশন একে অপরের সাথে একই সম্পর্কে থাকবে এবং যদি আমরা ক্রেটের মডিউল ট্রি পুনরায় সংগঠিত করার সিদ্ধান্ত নিই তবে একসাথে সরানো হবে। অতএব, আমরা super ব্যবহার করেছি যাতে ভবিষ্যতে যদি এই কোডটি অন্য কোনো মডিউলে সরানো হয় তবে আমাদের কম জায়গায় কোড আপডেট করতে হবে।

স্ট্রাকট এবং এনামগুলোকে পাবলিক করা (Making Structs and Enums Public)

আমরা স্ট্রাকট এবং এনামগুলোকেও পাবলিক হিসাবে মনোনীত করতে pub ব্যবহার করতে পারি, কিন্তু স্ট্রাকট এবং এনামগুলোর সাথে pub ব্যবহারের কয়েকটি অতিরিক্ত বিবরণ রয়েছে। যদি আমরা একটি স্ট্রাকট সংজ্ঞার আগে pub ব্যবহার করি, তাহলে আমরা স্ট্রাকটটিকে পাবলিক করি, কিন্তু স্ট্রাকটের ফিল্ডগুলো এখনও প্রাইভেট থাকবে। আমরা প্রতিটি ফিল্ডকে কেস-বাই-কেস ভিত্তিতে পাবলিক করতে পারি বা নাও করতে পারি। Listing 7-9-এ, আমরা একটি পাবলিক toast ফিল্ড কিন্তু একটি প্রাইভেট seasonal_fruit ফিল্ড সহ একটি পাবলিক back_of_house::Breakfast স্ট্রাকট সংজ্ঞায়িত করেছি। এটি একটি রেস্তোরাঁর ক্ষেত্রটিকে মডেল করে যেখানে গ্রাহক খাবারের সাথে আসা রুটির টাইপ বেছে নিতে পারে, কিন্তু শেফ সিদ্ধান্ত নেন কোন ফল পরিবেশন করা হবে, সেটি সিজনে কী আছে এবং স্টকে কী আছে তার উপর ভিত্তি করে। উপলব্ধ ফল দ্রুত পরিবর্তন হয়, তাই গ্রাহকরা ফল বেছে নিতে পারে না বা এমনকি তারা কোন ফল পাবে তাও দেখতে পায় না।

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,
        seasonal_fruit: String,
    }

    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
            }
        }
    }
}

pub fn eat_at_restaurant() {
    // Order a breakfast in the summer with Rye toast.
    let mut meal = back_of_house::Breakfast::summer("Rye");
    // Change our mind about what bread we'd like.
    meal.toast = String::from("Wheat");
    println!("I'd like {} toast please", meal.toast);

    // The next line won't compile if we uncomment it; we're not allowed
    // to see or modify the seasonal fruit that comes with the meal.
    // meal.seasonal_fruit = String::from("blueberries");
}

যেহেতু back_of_house::Breakfast স্ট্রাকটের toast ফিল্ডটি পাবলিক, তাই eat_at_restaurant-এ আমরা ডট নোটেশন ব্যবহার করে toast ফিল্ডে লিখতে এবং পড়তে পারি। লক্ষ্য করুন যে আমরা eat_at_restaurant-এ seasonal_fruit ফিল্ডটি ব্যবহার করতে পারি না, কারণ seasonal_fruit প্রাইভেট। seasonal_fruit ফিল্ডের মান পরিবর্তন করার লাইনটি আনকমেন্ট করার চেষ্টা করুন, দেখুন আপনি কী এরর পান!

এছাড়াও, মনে রাখবেন যে যেহেতু back_of_house::Breakfast-এর একটি প্রাইভেট ফিল্ড রয়েছে, তাই স্ট্রাকটটির একটি পাবলিক অ্যাসোসিয়েটেড ফাংশন সরবরাহ করা দরকার যা Breakfast-এর একটি ইন্সট্যান্স তৈরি করে (আমরা এখানে এটির নাম দিয়েছি summer)। যদি Breakfast-এর এমন কোনো ফাংশন না থাকত, তাহলে আমরা eat_at_restaurant-এ Breakfast-এর একটি ইন্সট্যান্স তৈরি করতে পারতাম না কারণ আমরা eat_at_restaurant-এ প্রাইভেট seasonal_fruit ফিল্ডের মান সেট করতে পারতাম না।

বিপরীতে, যদি আমরা একটি এনামকে পাবলিক করি, তাহলে এর সমস্ত ভেরিয়েন্ট পাবলিক হয়ে যায়। আমাদের শুধুমাত্র enum কীওয়ার্ডের আগে pub প্রয়োজন, যেমনটি Listing 7-10-এ দেখানো হয়েছে।

mod back_of_house {
    pub enum Appetizer {
        Soup,
        Salad,
    }
}

pub fn eat_at_restaurant() {
    let order1 = back_of_house::Appetizer::Soup;
    let order2 = back_of_house::Appetizer::Salad;
}

যেহেতু আমরা Appetizer এনামটিকে পাবলিক করেছি, তাই আমরা eat_at_restaurant-এ Soup এবং Salad ভেরিয়েন্টগুলো ব্যবহার করতে পারি।

এনামগুলো খুব একটা দরকারী নয় যদি না তাদের ভেরিয়েন্টগুলো পাবলিক হয়; প্রতিটি ক্ষেত্রে সমস্ত এনাম ভেরিয়েন্টকে pub দিয়ে অ্যানোটেট করতে হলে বিরক্তিকর হবে, তাই এনাম ভেরিয়েন্টগুলোর জন্য ডিফল্ট হল পাবলিক হওয়া। স্ট্রাকটগুলো প্রায়শই তাদের ফিল্ডগুলো পাবলিক না করেই দরকারী, তাই স্ট্রাকট ফিল্ডগুলো সবকিছু ডিফল্টরূপে প্রাইভেট হওয়ার সাধারণ নিয়ম অনুসরণ করে, যদি না pub দিয়ে অ্যানোটেট করা হয়।

pub জড়িত আরও একটি পরিস্থিতি রয়েছে যা আমরা কভার করিনি, এবং সেটি হল আমাদের শেষ মডিউল সিস্টেম ফিচার: use কীওয়ার্ড। আমরা প্রথমে use নিয়ে নিজে থেকেই আলোচনা করব, এবং তারপর আমরা দেখাব কিভাবে pub এবং use একত্রিত করতে হয়।