@@ -273,6 +273,96 @@ One last thing about traits: generic functions with a trait bound use
273273dispatched. What's that mean? Check out the chapter on [ static and dynamic
274274dispatch] ( static-and-dynamic-dispatch.html ) for more.
275275
276+ ## Where clause
277+
278+ Writing functions with only a few generic types and a small number of trait
279+ bounds isn't too bad, but as the number increases, the syntax gets increasingly
280+ awkward:
281+
282+ ```
283+ use std::fmt::Debug;
284+
285+ fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
286+ x.clone();
287+ y.clone();
288+ println!("{:?}", y);
289+ }
290+ ```
291+
292+ The name of the function is on the far left, and the parameter list is on the
293+ far right. The bounds are getting in the way.
294+
295+ Rust has a solution, and it's called a '` where ` clause':
296+
297+ ```
298+ use std::fmt::Debug;
299+
300+ fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
301+ x.clone();
302+ y.clone();
303+ println!("{:?}", y);
304+ }
305+
306+ fn bar<T, K>(x: T, y: K) where T: Clone, K: Clone + Debug {
307+ x.clone();
308+ y.clone();
309+ println!("{:?}", y);
310+ }
311+
312+ fn main() {
313+ foo("Hello", "world");
314+ bar("Hello", "workd");
315+ }
316+ ```
317+
318+ ` foo() ` uses the syntax we showed earlier, and ` bar() ` uses a ` where ` clause.
319+ All you need to do is leave off the bounds when defining your type parameters,
320+ and then add ` where ` after the parameter list. For longer lists, whitespace can
321+ be added:
322+
323+ ```
324+ use std::fmt::Debug;
325+
326+ fn bar<T, K>(x: T, y: K)
327+ where T: Clone,
328+ K: Clone + Debug {
329+
330+ x.clone();
331+ y.clone();
332+ println!("{:?}", y);
333+ }
334+ ```
335+
336+ This flexibility can add clarity in complex situations.
337+
338+ ` where ` is also more powerful than the simpler syntax. For example:
339+
340+ ```
341+ trait ConvertTo<Output> {
342+ fn convert(&self) -> Output;
343+ }
344+
345+ impl ConvertTo<i64> for i32 {
346+ fn convert(&self) -> i64 { *self as i32 }
347+ }
348+
349+ // can be called with T == i32
350+ fn normal<T: ConvertTo<i64>>(x: &T) -> i64 {
351+ x.convert()
352+ }
353+
354+ // can be called with T == i64
355+ fn inverse<T>() -> T
356+ // this is using ConvertTo as if it were "ConvertFrom<i32>"
357+ where i32: ConvertTo<T> {
358+ 1i32.convert()
359+ }
360+ ```
361+
362+ This shows off the additional feature of ` where ` clauses: they allow bounds
363+ where the left-hand side is an arbitrary type (` i32 ` in this case), not just a
364+ plain type parameter (like ` T ` ).
365+
276366## Our ` inverse ` Example
277367
278368Back in [ Generics] ( generics.html ) , we were trying to write code like this:
0 commit comments