@@ -940,332 +940,19 @@ fn foo(x: int) -> int {
940
940
There are some additional ways to define functions, but they involve features
941
941
that we haven't learned about yet, so let's just leave it at that for now.
942
942
943
-
944
943
## Comments
945
944
946
- Now that we have some functions, it's a good idea to learn about comments.
947
- Comments are notes that you leave to other programmers to help explain things
948
- about your code. The compiler mostly ignores them.
949
-
950
- Rust has two kinds of comments that you should care about: ** line comment** s
951
- and ** doc comment** s.
952
-
953
- ``` {rust}
954
- // Line comments are anything after '//' and extend to the end of the line.
955
-
956
- let x = 5i; // this is also a line comment.
957
-
958
- // If you have a long explanation for something, you can put line comments next
959
- // to each other. Put a space between the // and your comment so that it's
960
- // more readable.
961
- ```
962
-
963
- The other kind of comment is a doc comment. Doc comments use ` /// ` instead of
964
- ` // ` , and support Markdown notation inside:
945
+ return
965
946
966
- ``` {rust}
967
- /// `hello` is a function that prints a greeting that is personalized based on
968
- /// the name given.
969
- ///
970
- /// # Arguments
971
- ///
972
- /// * `name` - The name of the person you'd like to greet.
973
- ///
974
- /// # Example
975
- ///
976
- /// ```rust
977
- /// let name = "Steve";
978
- /// hello(name); // prints "Hello, Steve!"
979
- /// ```
980
- fn hello(name: &str) {
981
- println!("Hello, {}!", name);
982
- }
983
- ```
984
-
985
- When writing doc comments, adding sections for any arguments, return values,
986
- and providing some examples of usage is very, very helpful.
987
-
988
- You can use the ` rustdoc ` tool to generate HTML documentation from these doc
989
- comments. We will talk more about ` rustdoc ` when we get to modules, as
990
- generally, you want to export documentation for a full module.
947
+ comments
991
948
992
949
## Compound Data Types
993
950
994
- Rust, like many programming languages, has a number of different data types
995
- that are built-in. You've already done some simple work with integers and
996
- strings, but next, let's talk about some more complicated ways of storing data.
997
-
998
- ### Tuples
999
-
1000
- The first compound data type we're going to talk about are called ** tuple** s.
1001
- Tuples are an ordered list of a fixed size. Like this:
1002
-
1003
- ``` rust
1004
- let x = (1i , " hello" );
1005
- ```
1006
-
1007
- The parenthesis and commas form this two-length tuple. Here's the same code, but
1008
- with the type annotated:
1009
-
1010
- ``` rust
1011
- let x : (int , & str ) = (1 , " hello" );
1012
- ```
1013
-
1014
- As you can see, the type of a tuple looks just like the tuple, but with each
1015
- position having a type name rather than the value. Careful readers will also
1016
- note that tuples are heterogeneous: we have an ` int ` and a ` &str ` in this tuple.
1017
- You haven't seen ` &str ` as a type before, and we'll discuss the details of
1018
- strings later. In systems programming languages, strings are a bit more complex
1019
- than in other languages. For now, just read ` &str ` as "a string slice," and
1020
- we'll learn more soon.
1021
-
1022
- You can access the fields in a tuple through a ** destructuring let** . Here's
1023
- an example:
1024
-
1025
- ``` rust
1026
- let (x , y , z ) = (1i , 2i , 3i );
1027
-
1028
- println! (" x is {}" , x );
1029
- ```
1030
-
1031
- Remember before when I said the left hand side of a ` let ` statement was more
1032
- powerful than just assigning a binding? Here we are. We can put a pattern on
1033
- the left hand side of the ` let ` , and if it matches up to the right hand side,
1034
- we can assign multiple bindings at once. In this case, ` let ` 'destructures,'
1035
- or 'breaks up,' the tuple, and assigns the bits to three bindings.
1036
-
1037
- This pattern is very powerful, and we'll see it repeated more later.
1038
-
1039
- The last thing to say about tuples is that they are only equivalent if
1040
- the arity, types, and values are all identical.
1041
-
1042
- ``` rust
1043
- let x = (1i , 2i , 3i );
1044
- let y = (2i , 3i , 4i );
1045
-
1046
- if x == y {
1047
- println! (" yes" );
1048
- } else {
1049
- println! (" no" );
1050
- }
1051
- ```
1052
-
1053
- This will print ` no ` , as the values aren't equal.
1054
-
1055
- One other use of tuples is to return multiple values from a function:
1056
-
1057
- ``` rust
1058
- fn next_two (x : int ) -> (int , int ) { (x + 1i , x + 2i ) }
1059
-
1060
- fn main () {
1061
- let (x , y ) = next_two (5i );
1062
- println! (" x, y = {}, {}" , x , y );
1063
- }
1064
- ```
1065
-
1066
- Even though Rust functions can only return one value, a tuple _ is_ one value,
1067
- that happens to be made up of two. You can also see in this example how you
1068
- can destructure a pattern returned by a function, as well.
1069
-
1070
- Tuples are a very simple data structure, and so are not often what you want.
1071
- Let's move on to their bigger sibling, structs.
1072
-
1073
- ### Structs
1074
-
1075
- A struct is another form of a 'record type,' just like a tuple. There's a
1076
- difference: structs give each element that they contain a name, called a
1077
- 'field' or a 'member.' Check it out:
1078
-
1079
- ``` rust
1080
- struct Point {
1081
- x : int ,
1082
- y : int ,
1083
- }
1084
-
1085
- fn main () {
1086
- let origin = Point { x : 0i , y : 0i };
1087
-
1088
- println! (" The origin is at ({}, {})" , origin . x, origin . y);
1089
- }
1090
- ```
1091
-
1092
- There's a lot going on here, so let's break it down. We declare a struct with
1093
- the ` struct ` keyword, and then with a name. By convention, structs begin with a
1094
- capital letter and are also camel cased: ` PointInSpace ` , not ` Point_In_Space ` .
1095
-
1096
- We can create an instance of our struct via ` let ` , as usual, but we use a `key:
1097
- value` style syntax to set each field. The order doesn't need to be the same as
1098
- in the original declaration.
1099
-
1100
- Finally, because fields have names, we can access the field through dot
1101
- notation: ` origin.x ` .
1102
-
1103
- The values in structs are immutable, like other bindings in Rust. However, you
1104
- can use ` mut ` to make them mutable:
1105
-
1106
- ``` rust
1107
- struct Point {
1108
- x : int ,
1109
- y : int ,
1110
- }
1111
-
1112
- fn main () {
1113
- let mut point = Point { x : 0i , y : 0i };
1114
-
1115
- point . x = 5 ;
1116
-
1117
- println! (" The point is at ({}, {})" , point . x, point . y);
1118
- }
1119
- ```
1120
-
1121
- This will print ` The point is at (5, 0) ` .
1122
-
1123
- ### Tuple Structs and Newtypes
1124
-
1125
- Rust has another data type that's like a hybrid between a tuple and a struct,
1126
- called a ** tuple struct** . Tuple structs do have a name, but their fields
1127
- don't:
1128
-
1129
-
1130
- ```
1131
- struct Color(int, int, int);
1132
- struct Point(int, int, int);
1133
- ```
1134
-
1135
- These two will not be equal, even if they have the same values:
1136
-
1137
- ``` {rust,ignore}
1138
- let black = Color(0, 0, 0);
1139
- let origin = Point(0, 0, 0);
1140
- ```
1141
-
1142
- It is almost always better to use a struct than a tuple struct. We would write
1143
- ` Color ` and ` Point ` like this instead:
1144
-
1145
- ``` rust
1146
- struct Color {
1147
- red : int ,
1148
- blue : int ,
1149
- green : int ,
1150
- }
1151
-
1152
- struct Point {
1153
- x : int ,
1154
- y : int ,
1155
- z : int ,
1156
- }
1157
- ```
1158
-
1159
- Now, we have actual names, rather than positions. Good names are important,
1160
- and with a struct, we have actual names.
1161
-
1162
- There _ is_ one case when a tuple struct is very useful, though, and that's a
1163
- tuple struct with only one element. We call this a 'newtype,' because it lets
1164
- you create a new type that's a synonym for another one:
1165
-
1166
- ```
1167
- struct Inches(int);
1168
- struct Centimeters(int);
1169
-
1170
- let length = Inches(10);
1171
-
1172
- let Inches(integer_length) = length;
1173
- println!("length is {} inches", integer_length);
1174
- ```
951
+ Tuples
1175
952
1176
- As you can see here, you can extract the inner integer type through a
1177
- destructuring ` let ` .
1178
-
1179
- ### Enums
1180
-
1181
- Finally, Rust has a "sum type", an ** enum** . Enums are an incredibly useful
1182
- feature of Rust, and are used throughout the standard library. Enums look
1183
- like this:
1184
-
1185
- ```
1186
- enum Ordering {
1187
- Less,
1188
- Equal,
1189
- Greater,
1190
- }
1191
- ```
1192
-
1193
- This is an enum that is provided by the Rust standard library. An ` Ordering `
1194
- can only be _ one_ of ` Less ` , ` Equal ` , or ` Greater ` at any given time. Here's
1195
- an example:
1196
-
1197
- ``` rust
1198
- let x = 5i ;
1199
- let y = 10i ;
1200
-
1201
- let ordering = x . cmp (& y );
1202
-
1203
- if ordering == Less {
1204
- println! (" less" );
1205
- } else if ordering == Greater {
1206
- println! (" greater" );
1207
- } else if ordering == Equal {
1208
- println! (" equal" );
1209
- }
1210
- ```
1211
-
1212
- ` cmp ` is a function that compares two things, and returns an ` Ordering ` . The
1213
- call looks a little bit strange: rather than ` cmp(x, y) ` , we say ` x.cmp(&y) ` .
1214
- We haven't covered methods and references yet, so it should look a little bit
1215
- foreign. Right now, just pretend it says ` cmp(x, y) ` , and we'll get to those
1216
- details soon.
1217
-
1218
- The ` ordering ` variable has the type ` Ordering ` , and so contains one of the
1219
- three values. We can then do a bunch of ` if ` /` else ` comparisons to check
1220
- which one it is.
1221
-
1222
- However, repeated ` if ` /` else ` comparisons get quite tedious. Rust has a feature
1223
- that not only makes them nicer to read, but also makes sure that you never
1224
- miss a case. Before we get to that, though, let's talk about another kind of
1225
- enum: one with values.
1226
-
1227
- This enum has two variants, one of which has a value.:
1228
-
1229
- ```
1230
- enum OptionalInt {
1231
- Value(int),
1232
- Missing
1233
- }
1234
-
1235
- fn main() {
1236
- let x = Value(5);
1237
- let y = Missing;
1238
-
1239
- match x {
1240
- Value(n) => println!("x is {:d}", n),
1241
- Missing => println!("x is missing!"),
1242
- }
1243
-
1244
- match y {
1245
- Value(n) => println!("y is {:d}", n),
1246
- Missing => println!("y is missing!"),
1247
- }
1248
- }
1249
- ```
1250
-
1251
- This enum represents an ` int ` that we may or may not have. In the ` Missing `
1252
- case, we have no value, but in the ` Value ` case, we do. This enum is specific
1253
- to ` int ` s, though. We can make it usable by any type, but we haven't quite
1254
- gotten there yet!
1255
-
1256
- You can have any number of values in an enum:
1257
-
1258
- ```
1259
- enum OptionalColor {
1260
- Color(int, int, int),
1261
- Missing
1262
- }
1263
- ```
953
+ Structs
1264
954
1265
- Enums with values are quite useful, but as I mentioned, they're even more
1266
- useful when they're generic across types. But before we get to generics, let's
1267
- talk about how to fix this big ` if ` /` else ` statements we've been writing. We'll
1268
- do that with ` match ` .
955
+ Enums
1269
956
1270
957
## Match
1271
958
0 commit comments