A lot of RFCs is published but until now, the "named arguments" still unavailable.
Thus, I want to know if there is some method for emulate the "named arguments".
I firstly found emulation here, which suggest using Struct::new().arg1(val1).arg2(val2)...
to achieve what we are doing with "named arguments".
But, things may be difficult since what we may not want to change the arguments after the `new()` is called...
let mut database=Database::new().capacity(10000000).row(13);
The difficult is, we should return a Database
with all the internal value, Database::new()
Database::new().capacity(10000000)
, Database::new().capacity(10000000).row(13)
and many possible solution like Database::new().row(2).capacity(10000000).row(13)
.
which means we should implement capacity
and row
for all Database
, which may be buggy.
Inspired by such grammar, I tried a pseudo marco:
let target=!Config::new().arg1(val1).arg2(val2)...
which is implemented by hacking `std::ops::Not`
#[derive(Debug)]
struct Cfg{
a:i32,
b:i32
}
#[derive(Debug)]
struct Target{
config:Cfg,
result:i32
}
impl Target{
fn new_with_config(config:Cfg)->Self{
Self{result:config.a+config.b,config:config}
}
}
use std::ops::Not;
impl Not for Cfg{
type Output=Target;
fn not(self)->Self::Output{
Self::Output::new_with_config(self)
}
}
impl Cfg{
fn new()->Self{Self{a:0,b:0}}
fn a(mut self,a:i32)->Self{self.a=a;self}
fn b(mut self,b:i32)->Self{self.b=b;self}
}
fn main(){
let build=!Cfg::new().a(5).b(3);
println!("{:?}",build);
}
this try avoid implement runtime changing at the cost of:
- adding a
!
- should manually hack
std::ops::{something}
- while hacking, I must type both
type Output=Target
andfn not(self)->Self::Output
, which is kind of verbose
I tried to avoid the !
, but found it is very difficult since there is no Assign
trait. and we could not using other *Assign
since let target+=Cfg::new();
is illegal.
what's more, if what we want is a function(e.g., PRNG that generate bools), it is quite hard to tell the meaning among,
PRNG_conf::new().ntype(PRNG::type::Bool).probability(0.1)
!PRNG_conf::new().ntype(PRNG::type::Bool).probability(0.1)
!!PRNG_conf::new().ntype(PRNG::type::Bool).probability(0.1)
Is there a better way for "named arguments"?