What does || mean?

I am looking at the code sample from Hyper:

hyper::server::Http::new().bind(&addr, **||** Ok(HelloWorld))

bind expects NewService but I give this structure and Result of Service instead. It is accepted by the compiler.

I thought it is a closure without a single argument, but I doubt now... I have read the book, but maybe I missed this bit :slight_smile:

Could you please clarify what is the purpose of ||? how is the variable casting processed here to satisfy type constraints (Result of Service to NewService)? what happens under the hood?

1 Like

As you guessed, it is a closure with 0 arguments.

From the Hyper docs, the signature of Http::bind is:

fn bind<S, Bd>(
    &self, 
    addr: &SocketAddr, 
    new_service: S
) -> Result<Server<S, Bd>> where
    S: NewService<Request = hyper::Request, Response = hyper::Response<Bd>, Error = hyper::Error> + 'static,
    Bd: Stream<Item = B, Error = hyper::Error>;

In this signature the new_service argument can have any type S as long as S implements NewService. The rustdoc for NewService shows that there is at least one implementation:

impl<F, R> NewService for F where
    F: Fn() -> Result<R, hyper::Error>,
    R: Service;

So any type F can be used as an implementation of NewService, as long as F implements Fn() -> Result<R, Error> which is the trait for Rust closures that do not mutate any internal state, take 0 arguments, and return a Result<R, Error>.

The types signatures are pretty messy but to summarize:

  • || Ok(HelloWorld) is a closure that takes 0 arguments and returns Result<R, hyper::Error>. The type R is inferred based on the type of HelloWorld.
  • Due to the impl NewService for F shown above, the closure implements the NewService trait.
  • Since the closure implements the NewService trait, it can be passed as the new_service argument of type S to the Http::bind method.
3 Likes

Thanks. It explains everything.

1 Like