Questions on Trait Bounds

Is there any difference (besides syntax) between the following 2 ways of trait bounds?

fn my_fun<T: AsPrimitive<usize>>(x: T) -> f64 {
    ...
}

vs

fn my_fun<T>(x: T) -> f64 where T: AsPrimitive<usize> {
   ...
}

No. They're strictly identical.

1 Like

Why does Rust support both syntaxes which are strictly identical? I thought many programming languages prefer "one way" to solve a specific problem.

The former is a syntax sugar for the common cases. It doesn't have the full power of the where clause, but it's shorter for non-complex requirements.

4 Likes

Get it. Thank you so much!

I don't think it has any more "power", does it? It's just an alternative way of expressing exactly the same thing. I prefer the where syntax. The book says the "function’s signature is less cluttered" ,There is also the impl Trait syntax, which I think is less powerful, although as I don't use it I am not sure!

"Power" might not be the perfect word, but a where clause like where i32: Foo<T> can't be put in the inside-the-<>s version.

4 Likes

The shorthand can only describe bounds on type parameters, but where clauses can describe them for any type. For example:

fn f<I>(iter: I) where I: Iterator, I::Item: AsRef<u32> { ... }

Yes, agreed. But for the case of a parameter, the where syntax doesn't give you any extra power, is what I mean.

The where keyword was added in Rust 0.12, fairly late in Rust’s pre-1.0 development. Earlier versions had only the <T: Trait> syntax. The rationale for the new syntax is given in RFC 135.

Removing the old syntax was considered at the time, but the RFC says:

I decided against this both to avoid breaking lots of existing code and because the existing syntax is convenient much of the time.

4 Likes

It does.

impl<'lt> WithLifetime<'lt> {
    fn f<'x>(self, _: Cell<&'x str>) where 'lt: 'x {}
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.