ফাংশন হলো কোডের এমন অংশ, যেখানে এক বা একাধিক স্টেটমেন্ট বা এক্সপ্রেশন থাকে। একটি ফাংশন চাইলে একটি মান রিটার্নও করতে পারে।
Rust-এর রীতি হলো ফাংশনের নামে স্নেক কেস ব্যবহার করা, আর ফাংশন ডিফাইন করার সময় নামটির আগে fn কিওয়ার্ড বসে। যেমন
fn do_nothing() {}
প্রথম বন্ধনীর ভেতরে কমা দিয়ে আলাদা করা শূন্য বা তার বেশি প্যারামিটার থাকে। প্যারামিটার হলো নির্দিষ্ট টাইপের এমন একটি মানের বাইন্ডিং, যা ফাংশনে পাস করা হয়। প্যারামিটার না থাকলেও ফাংশন ডিফাইনে প্রথম বন্ধনী থাকা আবশ্যক। প্যারামিটারে যে বাস্তব মানটি পাস করা হয়, তাকে আর্গুমেন্ট বলা হয়।
প্যারামিটার আর রিটার্ন ভ্যালুর এই সমন্বয়কে ফাংশনের সিগনেচার বলা হয়। ফাংশনের সিগনেচারে প্রতিটি প্যারামিটারের টাইপ অ্যানোটেট করা থাকতে হয়।
দ্বিতীয় বন্ধনী ফাংশনের বডি ধারণ করে: এর স্টেটমেন্ট আর এক্সপ্রেশন। ফাংশনে কোনো স্টেটমেন্ট বা এক্সপ্রেশন না থাকলেও ফাংশন ডিফাইনের জন্য দ্বিতীয় বন্ধনী থাকা আবশ্যক।
নিচের উদাহরণে ফাংশনটি i32 টাইপের একটি প্যারামিটার নেয়, এটিকে value নামে বাইন্ড করে এবং এটি প্রিন্ট করে।
fn print_integer(value: i32) {
println!("{value:?}");
}
প্যারামিটারের ডেফিনিশনটি লক্ষ্য করুন। প্রতিটি প্যারামিটার name: Type ফরম্যাটে ডিফাইন করা হয়।
একটি ফাংশন একটি মান রিটার্নও করতে পারে। ডিফল্টভাবে শেষ এক্সপ্রেশনের আউটপুটটাই রিটার্ন করা হয়। নিচের উদাহরণে ফাংশনটির একটি i32 প্যারামিটার আছে এবং এটি তার দ্বিগুণ রিটার্ন করে।
fn double_integer(value: i32) -> i32 {
value * 2
}
-> i32 বোঝায় যে ফাংশনটি একটি i32 রিটার্ন করে। প্যারামিটারের মতো নয়, রিটার্ন করা মানটির কোনো নাম থাকে না।
return কিওয়ার্ড দিয়ে একটি ফাংশন থেকে আগেভাগেই বেরিয়ে আসা সম্ভব, এভাবে:
fn long_function() -> i32 {
let some_condition = false;
// code snipped
if (some_condition) {
return 0;
}
// more code snipped
42
}
কনস্ট্যান্ট ফাংশন ডিফাইনে const fn ব্যবহার করা হয়, যেটি কম্পাইল টাইমে হিসাব করা যায়।
const fn compute_data_checksum() -> u128 {
const DATA: &[u8] = include_bytes!("my_big_data_file");
// checksum implementation is left as an exercise for the reader
}
/// This checksum is used to validate that the user has not tampered with proprietary configuration.
pub const DATA_CHECKSUM: u128 = compute_data_checksum();
যেহেতু কনস্ট্যান্ট ফাংশন কম্পাইল টাইমে হিসাব করা যায়, তাই সাধারণ ফাংশনের তুলনায় এদের কিছু সীমাবদ্ধতা থাকে। বিশেষ করে, একটি const fn কেবল সেইসব ফাংশনকেই কল করতে পারে যেগুলোও const হিসেবে চিহ্নিত। এই সীমাবদ্ধতা না মানলে কম্পাইল এরর হয়।
const fn multiply_integer(value: i32) -> i32 {
use std::time::SystemTime;
if SystemTime::now().elapsed().unwrap().as_nanos() == 0 { // this line errors
value * 2
} else {
value * 3
}
}
অ্যানোনিমাস ফাংশনও আছে, যেগুলো নিয়ে closures টপিকে আলোচনা করা হয়েছে।