What's the difference between returning Ok(()); and Ok(())

fn dispatch<Tx>(&mut self, tx_token: Tx, timestamp: Instant,
                    packet: ip::Packet) -> Result<()>
{
    Ok(())//works
    Ok(());//won't work
}

why without the semicolon it works? By the way, what () means? Why some functions return Result<()> instead of simple Result?

First, about Ok(()) vs Ok(());. The first thing is an expression, which evaluates to itself; the second is only statement. When the last statement in the block (including function body) is an expression, the block will evaluate to this expression; if the last statement is not an expression, however, block evaluates to unit, which is not of type Result<()>.

Second, about Result. This is generic type, with - in the most common form - two parameters: the "success type" and the "error type", which must always be substituted. You are most likely using something like io::Result, which is the common Result with fixed error type, so that you have to fill in only the "success" type - but you still have to fill it in. And here the unit type, written as (), comes into play: it is a type of values which are not really values. It simply serves as a mark that the program reached some state, in this case - that the function returned successfully.

where can I read more about the difference between putting a semicolon and not?

There is some discussion in the Functions section of the book:

Let’s look at another example:

Filename: src/main.rs

fn main() {
    let x = plus_one(5);

    println!("The value of x is: {}", x);
}

fn plus_one(x: i32) -> i32 {
    x + 1
}

Running this code will print The value of x is: 6 . But if we place a semicolon at the end of the line containing x + 1 , changing it from an expression to a statement, we’ll get an error.

Filename: src/main.rs

fn main() {
    let x = plus_one(5);

    println!("The value of x is: {}", x);
}

fn plus_one(x: i32) -> i32 {
    x + 1;
}

Compiling this code produces an error, as follows:

$ cargo run
   Compiling functions v0.1.0 (file:///projects/functions)
error[E0308]: mismatched types
 --> src/main.rs:7:24
  |
7 | fn plus_one(x: i32) -> i32 {
  |    --------            ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression
8 |     x + 1;
  |          - help: consider removing this semicolon

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `functions`.

To learn more, run the command again with --verbose.

The main error message, “mismatched types,” reveals the core issue with this code. The definition of the function plus_one says that it will return an i32 , but statements don’t evaluate to a value, which is expressed by () , an empty tuple. Therefore, nothing is returned, which contradicts the function definition and results in an error. In this output, Rust provides a message to possibly help rectify this issue: it suggests removing the semicolon, which would fix the error.

In short, if you leave off the semi-colon it "returns" the value to the outer scope. In this context:

fn func() -> Result<()> {
    Ok(())
}

Is equivalent to

fn func() -> Result<()> {
    return Ok(());
}

But note that this isn't always the same as using the return statement. For example:

let value = if result.is_ok() {
    42
} else {
    0
};
// `value` is now either 42 or 0.

Here the numbers are "returned" from the if statement. But unlike the return statement it doesn't cause the function to return.