Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

মডিউল ট্রি-তে কোনো আইটেম রেফার করার জন্য পাথ

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

একটি পাথ দুই ধরনের হতে পারে:

  • একটি অ্যাবসোলিউট পাথ (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 ফাংশনের জন্য আমাদের কাছে সঠিক পাথ রয়েছে, কিন্তু রাস্ট আমাদের সেগুলি ব্যবহার করতে দেবে না কারণ এটি প্রাইভেট সেকশন অ্যাক্সেস করতে পারে না। রাস্ট-এ, সমস্ত আইটেম (ফাংশন, মেথড, struct, enum, মডিউল, এবং ধ্রুবক) ডিফল্টরূপে প্যারেন্ট মডিউলের কাছে প্রাইভেট থাকে। আপনি যদি কোনো ফাংশন বা struct-এর মতো আইটেমকে প্রাইভেট করতে চান তবে সেটিকে একটি মডিউলের মধ্যে রাখুন।

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

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

pub কীওয়ার্ড দিয়ে পাথ এক্সপোজ করা

আসুন 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 ফাংশনটি প্রাইভেট। প্রাইভেসি নিয়ম struct, enum, ফাংশন, এবং মেথডের পাশাপাশি মডিউলের ক্ষেত্রেও প্রযোজ্য।

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

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 দেখুন।

একটি বাইনারি এবং একটি লাইব্রেরি সহ প্যাকেজের জন্য সেরা অভ্যাস

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

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

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

super দিয়ে রিলেটিভ পাথ শুরু করা

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

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

Struct এবং Enum-কে পাবলিক করা

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

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 struct-এর toast ফিল্ডটি পাবলিক, তাই eat_at_restaurant-এ আমরা ডট নোটেশন ব্যবহার করে toast ফিল্ডে লিখতে এবং পড়তে পারি। লক্ষ্য করুন যে আমরা eat_at_restaurant-এ seasonal_fruit ফিল্ডটি ব্যবহার করতে পারি না, কারণ seasonal_fruit প্রাইভেট। seasonal_fruit ফিল্ডের মান পরিবর্তনকারী লাইনটি আনকমেন্ট করে চেষ্টা করুন কী এরর পান তা দেখতে!

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

এর বিপরীতে, যদি আমরা একটি enum-কে পাবলিক করি, তবে এর সমস্ত ভ্যারিয়েন্ট তখন পাবলিক হয়ে যায়। আমাদের কেবল 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 enum-কে পাবলিক করেছি, তাই আমরা eat_at_restaurant-এ Soup এবং Salad ভ্যারিয়েন্টগুলো ব্যবহার করতে পারি।

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

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