Lion Li
Lion Li

Reputation: 87

What do four consecutive vertical lines mean?

In the following code snippet:

let read_pool = ReadPool::new(
    "readpool",
    &Config::default_for_test(),
    || || Context {}
);

What are the four vertical lines || ||?

Upvotes: 7

Views: 2253

Answers (3)

ljedrz
ljedrz

Reputation: 22253

According to that function's source this pattern is called a closure builder:

// Rust does not support copying closures (RFC 2132) so that we need a closure builder.

// TODO: Use a single closure once RFC 2132 is implemented.

The related code fragments reveal that this argument is a function or closure returning another one, both without arguments (which || || Context {} adheres to):

// src/server/readpool/mod.rs

pub fn new<F, CF>(name_prefix: &str, 
                  config: &Config, 
                  context_factory_builder: F // this is the argument in question
) -> Self where
    F: futurepool::Factory<CF>,
    CF: futurepool::Factory<T>

// src/util/futurepool.rs:

pub trait Factory<T> {
    fn build(&self) -> T;
}

impl<T, F> Factory<T> for F
    where F: Fn() -> T // a function taking no arguments
{
    fn build(&self) -> T {
        self()
    }
}

Upvotes: 3

Matthieu M.
Matthieu M.

Reputation: 300049

In Rust, || introduces a lambda (an unnamed function).

The arguments of the lambda are specified in between the two:

  • |a, b| a + b: a lambda taking 2 arguments a and b and returning their sum,
  • || println!("Hello, World"): a lambda taking no argument and printing "Hello, World!".

Since the body of a lambda is just an expression, it can be another lambda:

  • || || println!("Hello, World"): a lambda taking no argument and returning a lambda taking no argument and printing "Hello, World!".

Therefore, || || Context {} is simply:

  • a lambda taking no argument and returning || Context {},
  • which is a lambda taking no argument and returning an instance of Context.

Upvotes: 7

FauxFaux
FauxFaux

Reputation: 2515

|| represents a lambda taking no arguments.

fn main() {
    let a = || println!("hello");
    let b = || { println!("world") };

    a(); // hello
    b(); // world
}

Two together is a lambda returning another lambda:

fn main() {
    let a = || || println!("hello world");

    let c = a();
    c(); // hello world
}

Upvotes: 15

Related Questions