Co

Collect মধ্যে Rust

{one: "১টি অনুশীলনী", other: "%{count}টি অনুশীলনী"}

Collect সম্পর্কে

collect ফাংশনটি বুঝতে হলে আগে জানা দরকার যে এটি একটি ইটারেটর রিজলভ করতে ব্যবহৃত হয়। মনে করুন, একটি ইটারেটর আসলে আইটেমের একটি ক্রম, যা অন্য ইটারেটরের সঙ্গে চেইন করা যায়। ইটারেটরগুলো অলস, অর্থাৎ আপনি ইটারেটরটি কনজিউম করে এমন কোনো কোড কল না করলে তারা রান করে না। এমন কোডের মধ্যে আছে for লুপ আর কনজিউমিং অ্যাডাপ্টর। কনজিউমিং অ্যাডাপ্টর ইটারেটরের সব আইটেম প্রসেস করে কোনো একটি আউটপুট তৈরি করে।

collect তেমনই একটি কনজিউমিং অ্যাডাপ্টর, যা FromIterator ট্রেইট ইমপ্লিমেন্ট করে এমন যেকোনো টাইপের একটি ইনস্ট্যান্স তৈরি করতে ব্যবহার করা যায়। স্ট্যান্ডার্ড লাইব্রেরির সব কালেকশনের জন্যই ওই ট্রেইটটি ইমপ্লিমেন্ট করা আছে। যেহেতু FromIterator অনেক টাইপের জন্য ইমপ্লিমেন্ট করা আছে, তাই আপনি কোন ধরনের কালেকশন চান, সেটি Rust-কে জানাতে হবে। উদাহরণস্বরূপ, একটি স্ট্রিং স্লাইস থেকে আমরা যদি Vec<char> চাই, তাহলে collect-এর কলে টাইপটি এভাবে বসাতে পারি

    let my_chars = "Hello, World!".chars().collect::<Vec<char>>();
// since the item type of the `String::chars()` iterator can be inferred to be `char`, we can omit that information
// let my_chars = "Hello, World!".chars().collect::<Vec<_>>();

ডাবল কোলন আর বাইরের অ্যাঙ্গেল ব্র্যাকেটগুলো (অর্থাৎ ::<_>) turbofish নামে পরিচিত। এক্ষেত্রে turbofish আমাদের দরকারের চেয়ে বেশি সিনট্যাক্স-গোলমাল। বাইন্ডিংয়ের গায়েই টাইপটা উল্লেখ করে দিলে collect কম সিনট্যাক্স-গোলমালেই বুঝে নিতে পারে এটি কোন কালেকশন তৈরি করবে।

    let my_chars: Vec<char> = "Hello, World!".chars().collect();
// or
// let my_chars: Vec<_> = "Hello, World!".chars().collect();

যদি আমরা উল্টো করা ক্যারেক্টারের একটি String চাইতাম, তাহলে সেটা এভাবে করতে পারতাম

    let rev_chars: String = "Hello, World!".chars().rev().collect();

Rust-এর টাইপ ইনফারেন্স এতটাই শক্তিশালী যে মাঝেমধ্যে আলাদা করে ইনলাইনে টাইপ উল্লেখ করার দরকারই পড়ে না:

fn get_reversed_chars(phrase: &str) -> Vec<char> {
    phrase.chars().rev().collect()
}

get_reversed_chars ফাংশনের রিটার্ন টাইপই collect ফাংশনকে বুঝিয়ে দেয় কোন কালেকশন রিটার্ন করতে হবে। তবে এখানে আমাদের Vec<_> নয়, Vec<char> উল্লেখ করতেই হবে, কারণ Rust ফাংশন সিগনেচারের জন্য টাইপ ইনফারেন্স করে না। এর উদ্দেশ্য হলো, কোড পড়ছে যে কেউ, সে যেন দ্রুত বুঝতে পারে একটি ফাংশন কী কী টাইপ নেয় আর কী রিটার্ন করে।

GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি নতুন একটি উইন্ডো বা ট্যাবে খুলবে