Skip to content

Implement From<T> for Option<T> #1402

Closed
@abonander

Description

@abonander
impl From<T> for Option<T> {
    fn from(val: T) -> Self {
        Option::Some(val)
    }
}

This is a trivial impl and I think it would help ergonomics in certain areas of API design. As an example, consider a method on a fictional I/O wrapper for setting a timeout:

struct Socket;

impl Socket {
    // Set the timeout, in seconds. Removes timeout if `None`.
    fn set_timeout<T: Into<Option<u64>>(&mut self, timeout: T) { /* .. */ }
}

This can be called in both of the following forms without needing separate methods for u64 and Option<u64>:

let mut socket = Socket;

socket.set_timeout(3600);
socket.set_timeout(None);

Currently, if this API wanted to take an Option<u64>, it would have to be invariant over it:

fn set_timeout(&mut self, timeout: Option<u64>);

Requiring Some everywhere:

socket.set_timeout(Some(3600));

I think the above is much cleaner.

There are existing APIs such as the following:

http://doc.rust-lang.org/nightly/std/net/struct.UdpSocket.html#method.set_read_timeout

which I think could be migrated relatively seamlessly. I think the only breakage would be if someone was referring to them by UFCS, so the addition of a type parameter would break resolution (maybe). A Crater run would probably help here.

Otherwise, I don't see much as far as downsides go, except maybe some brief confusion for newbies. However, I don't think it would take them long to realize, "Oh! It can take u64 or Option<u64>. Cool!" Then it's just another neat little feature of Rust. I don't think accidental conversions would be a problem, either.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiRelevant to the library API team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions