@@ -315,3 +315,76 @@ The names don't actually change to this, it's just for illustration. But
315
315
as you can see, there's no overhead of deciding which version to call here,
316
316
hence * statically dispatched* . The downside is that we have two copies of
317
317
the same function, so our binary is a little bit larger.
318
+
319
+ ## Our ` inverse ` Example
320
+
321
+ Back in [ Generics] ( generics.html ) , we were trying to write code like this:
322
+
323
+ ``` {rust,ignore}
324
+ fn inverse<T>(x: T) -> Result<T, String> {
325
+ if x == 0.0 { return Err("x cannot be zero!".to_string()); }
326
+
327
+ Ok(1.0 / x)
328
+ }
329
+ ```
330
+
331
+ If we try to compile it, we get this error:
332
+
333
+ ``` text
334
+ error: binary operation `==` cannot be applied to type `T`
335
+ ```
336
+
337
+ This is because ` T ` is too generic: we don't know if a random ` T ` can be
338
+ compared. For that, we can use trait bounds. It doesn't quite work, but try
339
+ this:
340
+
341
+ ``` {rust,ignore}
342
+ fn inverse<T: PartialEq>(x: T) -> Result<T, String> {
343
+ if x == 0.0 { return Err("x cannot be zero!".to_string()); }
344
+
345
+ Ok(1.0 / x)
346
+ }
347
+ ```
348
+
349
+ You should get this error:
350
+
351
+ ``` text
352
+ error: mismatched types:
353
+ expected `T`,
354
+ found `_`
355
+ (expected type parameter,
356
+ found floating-point variable)
357
+ ```
358
+
359
+ So this won't work. While our ` T ` is ` PartialEq ` , we expected to have another ` T ` ,
360
+ but instead, we found a floating-point variable. We need a different bound. ` Float `
361
+ to the rescue:
362
+
363
+ ```
364
+ use std::num::Float;
365
+
366
+ fn inverse<T: Float>(x: T) -> Result<T, String> {
367
+ if x == Float::zero() { return Err("x cannot be zero!".to_string()) }
368
+
369
+ let one: T = Float::one();
370
+ Ok(one / x)
371
+ }
372
+ ```
373
+
374
+ We've had to replace our generic ` 0.0 ` and ` 1.0 ` with the appropriate methods
375
+ from the ` Float ` trait. Both ` f32 ` and ` f64 ` implement ` Float ` , so our function
376
+ works just fine:
377
+
378
+ ```
379
+ # use std::num::Float;
380
+ # fn inverse<T: Float>(x: T) -> Result<T, String> {
381
+ # if x == Float::zero() { return Err("x cannot be zero!".to_string()) }
382
+ # let one: T = Float::one();
383
+ # Ok(one / x)
384
+ # }
385
+ println!("the inverse of {} is {:?}", 2.0f32, inverse(2.0f32));
386
+ println!("the inverse of {} is {:?}", 2.0f64, inverse(2.0f64));
387
+
388
+ println!("the inverse of {} is {:?}", 0.0f32, inverse(0.0f32));
389
+ println!("the inverse of {} is {:?}", 0.0f64, inverse(0.0f64));
390
+ ```
0 commit comments