An Interest In:
Web News this Week
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
- April 13, 2024
October 16, 2021 07:04 pm GMT
Original Link: https://dev.to/fmtweisszwerg/how-to-overload-method-in-rust-amount-of-args-differ-48id
How to overload method in Rust (amount of args differ).
Adapt version
$ rustc --versionrustc 1.55.0 (c8dfcfe04 2021-09-06)
If you want to overload methods that have different amount of args likes following
// Constructor with 2 args.fn new(arg0, arg1) -> Self { ...}// Constructor with 1 arg.fn new(arg) -> Self { ...}
Macro is your better friend.
So macro can be used for pseud-overloading.
Pseud-overloading with macro.
struct SampleStruct { ip_address: IpAddr, port_number: u16, sample_socket: socket2::Socket,}macro_rules! SampleStruct_new { ($str_ip:expr , $num_port:expr) => ({ let ip: IpAddr = $str_ip.parse::<IpAddr>() .unwrap_or_else( |_| { panic!("`address` MUST be an IPv4 address or IPv6 address.") }); SampleStruct { ip_address: ip, port_number: $num_port, sample_socket: Socket::new( if ip.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 }, Type::DGRAM, Some(Protocol::UDP) ).unwrap() } }); ($obj_SocketAddr:expr) => ({ SampleStruct { ip_address: $obj_SocketAddr.ip(), port_number: $obj_SocketAddr.port(), sample_socket: Socket::new( if $obj_SocketAddr.ip().is_ipv4() { Domain::IPV4 } else { Domain::IPV6 }, Type::DGRAM, Some(Protocol::UDP) ).unwrap() } });}
Then it uses as following:
fn main() { let foo = SampleStruct_new!("127.0.0.1", 12345); println!("IP address = {}, Port = {}", foo.ip_address.to_string(), foo.port_number); let ipv6_sock_addr = SocketAddr::new("::1".parse::<IpAddr>().unwrap(), 12345); let bar = SampleStruct_new!(ipv6_sock_addr); println!("IP address = {}, Port = {}", bar.ip_address.to_string(), bar.port_number);}
To see a sample code, go Rust playground
Generics with placeholder.
Generics with placeholder is also your frind. _:()
in impl
block means "this is unused argument".
trait SampleTrait<T, O> { fn new(address:T, port:O) -> SampleStruct;}impl SampleTrait<&str, u16> for SampleStruct { fn new(address: &str, port: u16) -> Self { let addr = address.to_string().parse::<IpAddr>() .unwrap_or_else( |_| { panic!("`address` MUST be an IPv4 address (dotted-decimal form) or an IPv6 address.") }); return SampleStruct { ip_address: addr, port_number: port, sample_socket: Socket::new( if addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 }, Type::DGRAM, Some(Protocol::UDP) ).unwrap() } }}impl SampleTrait<SocketAddr, ()> for SampleStruct { fn new(address: SocketAddr, _:()) -> Self { return SampleStruct { ip_address: address.ip(), port_number: address.port(), sample_socket: Socket::new( if address.ip().is_ipv4() { Domain::IPV4 } else { Domain:: IPV6 }, Type::DGRAM, Some(Protocol::UDP) ).unwrap() } }}
When calling fn new(address: SocketAddr, _:())
, the ()
MUST be passed to unused args. So it seems slightly ugly in this way.
fn main() { let foo = SampleStruct::new("127.0.0.1".to_string(), 12345); println!("IP address = {}, Port = {}", foo.ip_address.to_string(), foo.port_number); let ipv6_sock_addr = SocketAddr::new("::1".parse::<IpAddr>().unwrap(), 12345); let baz = SampleStruct::new(ipv6_sock_addr, ()); println!("IP address = {}, Port = {}", baz.ip_address.to_string(), baz.port_number);}
To see a sample code, go Rust playground
Original Link: https://dev.to/fmtweisszwerg/how-to-overload-method-in-rust-amount-of-args-differ-48id
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To