You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`.
4885
-
We can then use `T` inside the rest of the signature: `x` has type `T`, and half
4886
-
of the `Result` has type `T`. However, if we try to compile that example, we'll get
4887
-
an error:
4885
+
Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`. We
4886
+
can then use `T` inside the rest of the signature: `x` has type `T`, and half of
4887
+
the `Result` has type `T`. However, if we try to compile that example, we'll get
4888
+
some errors:
4888
4889
4889
4890
```text
4890
4891
error: binary operation `==` cannot be applied to type`T`
4892
+
if x == 0.0 { return Err("x cannot be zero!".to_string()); }
4893
+
^~~~~~~~
4894
+
error: mismatched types: expected `_`, found `T` (expected floating-point variable, found type parameter)
4895
+
Ok(1.0 / x)
4896
+
^
4897
+
error: mismatched types: expected `core::result::Result<T, collections::string::String>`, found `core::result::Result<_, _>` (expected type parameter, found floating-point variable)
4898
+
Ok(1.0 / x)
4899
+
^~~~~~~~~~~
4891
4900
```
4892
4901
4893
-
Because `T` can be _any_ type, it may be a type that doesn't implement `==`,
4894
-
and therefore, the first line would be wrong. What do we do?
4902
+
The problem is that `T` is unconstrained: it can be _any_ type. It could be a
4903
+
`String`, and the expression `1.0 / x` has no meaning if`x` is a `String`. It
4904
+
may be a type that doesn't implement `==`, and the first line would be
4905
+
wrong. What do we do?
4895
4906
4896
-
To fix this example, we need to learn about another Rust feature: traits.
4907
+
To fix this example, we need to learn about another Rust feature: **traits**.
4897
4908
4898
4909
# Traits
4899
4910
4900
-
Do you remember the `impl` keyword, used to call a function with method
4901
-
syntax?
4911
+
Our discussion of **traits** begins with the `impl` keyword. We used it before
4912
+
to specify methods.
4902
4913
4903
4914
```{rust}
4904
4915
struct Circle {
@@ -4914,8 +4925,8 @@ impl Circle {
4914
4925
}
4915
4926
```
4916
4927
4917
-
Traits are similar, except that we define a trait with just the method
4918
-
signature, then implement the trait for that struct. Like this:
4928
+
We define a trait in terms of its methods. We then `impl` a trait `for` a type
4929
+
(or many types).
4919
4930
4920
4931
```{rust}
4921
4932
struct Circle {
@@ -4935,19 +4946,18 @@ impl HasArea for Circle {
4935
4946
}
4936
4947
```
4937
4948
4938
-
As you can see, the `trait` block looks very similar to the `impl` block,
4939
-
but we don't define a body, just a type signature. When we `impl` a trait,
4940
-
we use `impl Trait for Item`, rather than just `impl Item`.
4949
+
The `trait` block defines only type signatures. When we `impl` a trait, we use
4950
+
`impl Trait for Item`, rather than just `impl Item`.
4941
4951
4942
-
So what's the big deal? Remember the error we were getting with our generic
4943
-
`inverse` function?
4952
+
The first of the three errors we got with our generic `inverse` function was
4953
+
this:
4944
4954
4945
4955
```text
4946
4956
error: binary operation `==` cannot be applied to type `T`
4947
4957
```
4948
4958
4949
-
We can use traits to constrain our generics. Consider this function, which
4950
-
does not compile, and gives us a similar error:
4959
+
We can use traits to constrain generic type parameters. Consider this function,
4960
+
which does not compile, and gives us a similar error:
4951
4961
4952
4962
```{rust,ignore}
4953
4963
fn print_area<T>(shape: T) {
@@ -4962,8 +4972,9 @@ error: type `T` does not implement any method in scope named `area`
4962
4972
```
4963
4973
4964
4974
Because `T` can be any type, we can't be sure that it implements the `area`
4965
-
method. But we can add a **trait constraint** to our generic `T`, ensuring
4966
-
that it does:
4975
+
method. But we can add a **trait constraint** to our generic `T`, ensuring that
4976
+
we can only compile the functionif it's called with types which `impl` the
0 commit comments