ডিস্টেল আর্গুমেন্ট দিয়ে কোনও ফাংশন তৈরি করা কি জাস্টে সম্ভব?
fn add(a: int = 1, b: int = 2) { a + b }
ডিস্টেল আর্গুমেন্ট দিয়ে কোনও ফাংশন তৈরি করা কি জাস্টে সম্ভব?
fn add(a: int = 1, b: int = 2) { a + b }
Option
এবং স্পষ্টভাবে পাস করতে হবে None
।
উত্তর:
না, এটি বর্তমানে নেই। আমি মনে করি এটি সম্ভবত শেষ পর্যন্ত বাস্তবায়িত হবে তবে বর্তমানে এই জায়গাতে কোনও সক্রিয় কাজ নেই।
এখানে নিযুক্ত সাধারণ কৌশলটি বিভিন্ন নাম এবং স্বাক্ষর সহ ফাংশন বা পদ্ধতি ব্যবহার করা use
যেহেতু ডিফল্ট আর্গুমেন্টগুলি সমর্থন করে না আপনি ব্যবহার করে অনুরূপ আচরণ পেতে পারেন Option<T>
fn add(a: Option<i32>, b: Option<i32>) -> i32 {
a.unwrap_or(1) + b.unwrap_or(2)
}
এটি ডিফল্ট মান থাকার উদ্দেশ্য সাধন করে এবং ফাংশনটি কেবল একবার (প্রতিটি কলের পরিবর্তে) কোডিং করে তবে অবশ্যই আরও অনেক বেশি টাইপ করতে হবে। ফাংশন কলটি দেখতে পাবেন add(None, None)
যা আপনার দৃষ্টিভঙ্গির উপর নির্ভর করে আপনি পছন্দ করতে বা পছন্দ করতে পারেন।
আপনি যদি আর্গুমেন্টের তালিকায় কোনও কোড টাইপ করতে দেখেন যে কোডার সম্ভাব্যত কোনও পছন্দ করতে ভুলে যায় তবে এখানে বড় সুবিধাটি হ'ল এক্সপ্লিট সাক্ষীর মধ্যে; কলকারী স্পষ্টভাবে বলছে যে তারা আপনার ডিফল্ট মান নিয়ে যেতে চায় এবং তারা কিছুই না রাখলে একটি সংকলন ত্রুটি পাবে। এটি টাইপিং হিসাবে ভাবেন add(DefaultValue, DefaultValue)
।
আপনি ম্যাক্রোও ব্যবহার করতে পারেন:
fn add(a: i32, b: i32) -> i32 {
a + b
}
macro_rules! add {
($a: expr) => {
add($a, 2)
};
() => {
add(1, 2)
};
}
assert_eq!(add!(), 3);
assert_eq!(add!(4), 6);
দুটি সমাধানের মধ্যে বড় পার্থক্যটি হ'ল "বিকল্প" -র যুক্তিগুলির সাথে এটি লেখার পক্ষে সম্পূর্ণ বৈধ add(None, Some(4))
, তবে ম্যাক্রো প্যাটার্নের সাথে মিলে আপনি পারবেন না (এটি পাইথনের ডিফল্ট আর্গুমেন্টের নিয়মের অনুরূপ)।
আপনি "আর্গুমেন্ট" কাঠামো এবং From
/ Into
বৈশিষ্ট্যগুলিও ব্যবহার করতে পারেন :
pub struct FooArgs {
a: f64,
b: i32,
}
impl Default for FooArgs {
fn default() -> Self {
FooArgs { a: 1.0, b: 1 }
}
}
impl From<()> for FooArgs {
fn from(_: ()) -> Self {
Self::default()
}
}
impl From<f64> for FooArgs {
fn from(a: f64) -> Self {
Self {
a: a,
..Self::default()
}
}
}
impl From<i32> for FooArgs {
fn from(b: i32) -> Self {
Self {
b: b,
..Self::default()
}
}
}
impl From<(f64, i32)> for FooArgs {
fn from((a, b): (f64, i32)) -> Self {
Self { a: a, b: b }
}
}
pub fn foo<A>(arg_like: A) -> f64
where
A: Into<FooArgs>,
{
let args = arg_like.into();
args.a * (args.b as f64)
}
fn main() {
println!("{}", foo(()));
println!("{}", foo(5.0));
println!("{}", foo(-3));
println!("{}", foo((2.0, 6)));
}
এই পছন্দটি অবশ্যই অনেক বেশি কোড, তবে ম্যাক্রো ডিজাইনের বিপরীতে এটি টাইপ সিস্টেমটি ব্যবহার করে যার অর্থ সংকলক ত্রুটিগুলি আপনার গ্রন্থাগার / এপিআই ব্যবহারকারীর জন্য আরও সহায়ক হবে। এটি From
যদি ব্যবহারকারীদের পক্ষে সহায়ক হয় তবে তারা তাদের নিজস্ব বাস্তবায়ন করতে দেয়।
না, মরিচ ডিফল্ট ফাংশন যুক্তি সমর্থন করে না। আপনাকে বিভিন্ন নাম সহ বিভিন্ন পদ্ধতি নির্ধারণ করতে হবে। উভয়ই কোনও ক্রিয়াকলাপের ওভারলোডিং নেই, কারণ মরচে ধরণের ফাংশনের নামগুলি প্রকারভেদ করতে ব্যবহার করে (ফাংশন ওভারলোডিং এর বিপরীতে প্রয়োজন)।
স্ট্রাক্ট ইনিশিয়ালাইজের ক্ষেত্রে আপনি স্ট্রাক আপডেট সিনট্যাক্সটি এটির মতো ব্যবহার করতে পারেন:
use std::default::Default;
#[derive(Debug)]
pub struct Sample {
a: u32,
b: u32,
c: u32,
}
impl Default for Sample {
fn default() -> Self {
Sample { a: 2, b: 4, c: 6}
}
}
fn main() {
let s = Sample { c: 23, .. Sample::default() };
println!("{:?}", s);
}
[অনুরোধে, আমি একটি সদৃশ প্রশ্ন থেকে এই উত্তরটি ক্রস পোস্ট করেছি]
মরিচা ডিফল্ট ফাংশন আর্গুমেন্টকে সমর্থন করে না এবং আমি বিশ্বাস করি না এটি ভবিষ্যতে বাস্তবায়িত হবে। সুতরাং আমি ম্যাক্রো আকারে এটি বাস্তবায়নের জন্য একটি প্রো_ম্যাক্রো দুআআং লিখেছি ।
উদাহরণ স্বরূপ:
duang! ( fn add(a: i32 = 1, b: i32 = 2) -> i32 { a + b } );
fn main() {
assert_eq!(add!(b=3, a=4), 7);
assert_eq!(add!(6), 8);
assert_eq!(add(4,5), 9);
}
আপনি যদি মরিচা ১.১২ বা তার বেশি ব্যবহার করে থাকেন তবে আপনি কমপক্ষে ফাংশন আর্গুমেন্টগুলি এর সাথে Option
এবং আরও সহজে ব্যবহার করতে পারবেন into()
:
fn add<T: Into<Option<u32>>>(a: u32, b: T) -> u32 {
if let Some(b) = b.into() {
a + b
} else {
a
}
}
fn main() {
assert_eq!(add(3, 4), 7);
assert_eq!(add(8, None), 8);
}
অন্য উপায় হতে পারে বৈকল্পিক হিসাবে alচ্ছিক প্যারামগুলির সাথে একটি এনাম ঘোষণা করা, যা প্রতিটি বিকল্পের জন্য সঠিক ধরণের নিতে প্যারামিটারাইজ করা যেতে পারে। এনাম ভেরিয়েন্টগুলির একটি পরিবর্তনশীল দৈর্ঘ্যের টুকরো নিতে ফাংশনটি প্রয়োগ করা যেতে পারে। এগুলি যে কোনও ক্রম এবং দৈর্ঘ্যে হতে পারে। ডিফল্টগুলি প্রাথমিক কার্যাদি হিসাবে ফাংশনটির মধ্যে প্রয়োগ করা হয়।
enum FooOptions<'a> {
Height(f64),
Weight(f64),
Name(&'a str),
}
use FooOptions::*;
fn foo(args: &[FooOptions]) {
let mut height = 1.8;
let mut weight = 77.11;
let mut name = "unspecified".to_string();
for opt in args {
match opt {
Height(h) => height = *h,
Weight(w) => weight = *w,
Name(n) => name = n.to_string(),
}
}
println!(" name: {}\nweight: {} kg\nheight: {} m",
name, weight, height);
}
fn main() {
foo( &[ Weight(90.0), Name("Bob") ] );
}
আউটপুট:
name: Bob
weight: 90 kg
height: 1.8 m