How to overload method in Rust (amount of args differ).

Adapt version

$ rustc –version
rustc 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 {

}

// Cons…


This content originally appeared on DEV Community and was authored by Fomalhaut Weisszwerg

Adapt version

$ rustc --version
rustc 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


This content originally appeared on DEV Community and was authored by Fomalhaut Weisszwerg


Print Share Comment Cite Upload Translate Updates
APA

Fomalhaut Weisszwerg | Sciencx (2021-10-16T19:04:23+00:00) How to overload method in Rust (amount of args differ).. Retrieved from https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/

MLA
" » How to overload method in Rust (amount of args differ).." Fomalhaut Weisszwerg | Sciencx - Saturday October 16, 2021, https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/
HARVARD
Fomalhaut Weisszwerg | Sciencx Saturday October 16, 2021 » How to overload method in Rust (amount of args differ).., viewed ,<https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/>
VANCOUVER
Fomalhaut Weisszwerg | Sciencx - » How to overload method in Rust (amount of args differ).. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/
CHICAGO
" » How to overload method in Rust (amount of args differ).." Fomalhaut Weisszwerg | Sciencx - Accessed . https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/
IEEE
" » How to overload method in Rust (amount of args differ).." Fomalhaut Weisszwerg | Sciencx [Online]. Available: https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/. [Accessed: ]
rf:citation
» How to overload method in Rust (amount of args differ). | Fomalhaut Weisszwerg | Sciencx | https://www.scien.cx/2021/10/16/how-to-overload-method-in-rust-amount-of-args-differ/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.