@@ -273,6 +273,96 @@ One last thing about traits: generic functions with a trait bound use
273
273
dispatched. What's that mean? Check out the chapter on [ static and dynamic
274
274
dispatch] ( static-and-dynamic-dispatch.html ) for more.
275
275
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
+
276
366
## Our ` inverse ` Example
277
367
278
368
Back in [ Generics] ( generics.html ) , we were trying to write code like this:
0 commit comments