started revising for Rust 1.0; Ownership section done, started reference section
Getty Ritter
10 years ago
Binary diff not shown
| 1 | 1 | % The Rust Programming Language |
| 2 | 2 | % G.D. Ritter |
| 3 | % March 2014 | |
| 4 | ||
| 5 | # WARNING | |
| 6 | ||
| 7 | The following presentation is out of date, and may not ever be up-to-date | |
| 8 | again. Proceed with caution! | |
| 3 | % May 2015 | |
| 9 | 4 | |
| 10 | 5 | # The Rust Programming Language |
| 11 | 6 | |
| 50 | 45 | data Point = { x, y : Int } |
| 51 | 46 | |
| 52 | 47 | addPoint : Point -> Point -> Point |
| 53 |
addPoint |
|
| 48 | addPoint l r = { x = l.x + r.x, y = l.y + r.y } | |
| 54 | 49 | |
| 55 | 50 | main : () |
| 56 | 51 | main = { let a = { x = 1, y = 2 } |
| 98 | 93 | point a(1, 2); |
| 99 | 94 | point* b = new point(4, 3); |
| 100 | 95 | point c = a.add(*b); |
| 101 | std::cout << "{ .x = " << c.x; | |
| 102 | std::cout << ", .y = " << c.y << " }" << std::endl; | |
| 96 | cout << "{ .x = " << c.x; | |
| 97 | cout << ", .y = " << c.y << " }" << endl; | |
| 103 | 98 | delete b; |
| 104 | 99 | } |
| 105 | 100 | ~~~~ |
| 147 | 142 | |
| 148 | 143 | # Systems Programming Languages |
| 149 | 144 | |
| 150 |
## Nim |
|
| 145 | ## Nim | |
| 151 | 146 | |
| 152 | 147 | ~~~~ |
| 153 | 148 | type Point = tuple[x: int, y: int] |
| 171 | 166 | ## Rust |
| 172 | 167 | |
| 173 | 168 | ~~~~{.rust} |
| 174 |
struct Point { x: i |
|
| 169 | struct Point { x: isize, y: isize } | |
| 175 | 170 | |
| 176 | 171 | impl Point { |
| 177 | 172 | fn add(self, other: Point) -> Point { |
| 182 | 177 | |
| 183 | 178 | fn main() { |
| 184 | 179 | let a = Point { x: 1, y: 2 }; |
| 185 |
let b = |
|
| 180 | let b = Box::new(Point { x: 4, y: 3 }); | |
| 186 | 181 | println!("{:?}", a.add(*b)); |
| 187 | 182 | } |
| 188 | 183 | ~~~~ |
| 189 | 184 | |
| 190 | # Basics of Rust | |
| 191 | ||
| 192 |
# |
|
| 185 | # What Makes Rust Interesting | |
| 193 | 186 | |
| 194 | 187 | > It's like C++ grew up, went to grad school, started dating Haskell, and |
| 195 | 188 | > is sharing an office with Erlang... |
| 196 | 189 | > |
| 197 | 190 | > —Michael Sullivan |
| 198 | 191 | |
| 199 | # Basics of Rust | |
| 200 | ||
| 201 | ## Recursive Factorial | |
| 202 | ||
| 203 | ~~~~{.rust} | |
| 204 | fn fact1(n: int) -> int { | |
| 205 | if n <= 0 { | |
| 206 | 1 | |
| 207 | } else { | |
| 208 | n * fact1(n-1) | |
| 209 | } | |
| 210 | } | |
| 211 | ~~~~ | |
| 212 | ||
| 213 | ## Another Recursive Factorial | |
| 214 | ||
| 215 | ~~~~{.rust} | |
| 216 | fn fact2(n: int) -> int { | |
| 217 | match n { | |
| 218 | 0 => { 1 } | |
| 219 | _ => { n * fact2(n-1) } | |
| 220 | } | |
| 221 | } | |
| 222 | ~~~~ | |
| 223 | ||
| 224 | # Basics of Rust | |
| 225 | ||
| 226 | ## An Imperative Factorial | |
| 227 | ||
| 228 | ~~~~{.rust} | |
| 229 | fn fact3(mut n: int) -> int { | |
| 230 | let mut res = 1; | |
| 231 | while (n > 0) { | |
| 232 | res *= n; | |
| 233 | n -= 1; | |
| 234 | } | |
| 235 | res | |
| 236 | } | |
| 237 | ~~~~ | |
| 238 | ||
| 239 | ## One More Imperative Factorial | |
| 240 | ||
| 241 | ~~~~{.rust} | |
| 242 | fn fact4(mut n: int) -> int { | |
| 243 | for i in range(1, n) { n *= i; } | |
| 244 | return n; | |
| 245 | } | |
| 246 | ~~~~ | |
| 247 | ||
| 248 | # Basics of Rust | |
| 249 | ||
| 250 | ## Tuples | |
| 251 | ||
| 252 | ~~~~{.rust} | |
| 253 | { | |
| 254 | let t: (int, int, int) = (1,2,3); | |
| 255 | let (a,b,c) = t; | |
| 256 | let r = match t { (a,b,c) => a + b + c }; | |
| 257 | } | |
| 258 | ~~~~ | |
| 259 | ||
| 260 | ## Tuple Structs (i.e. named tuples) | |
| 261 | ||
| 262 | ~~~~{.rust} | |
| 263 | struct T(bool, int); | |
| 264 | fn f(t: T) -> int { | |
| 265 | let T(myBool, myInt) = t; | |
| 266 | return if myBool { myInt } else { -myInt }; | |
| 267 | } | |
| 268 | ~~~~ | |
| 269 | ||
| 270 | # Basics of Rust | |
| 271 | ||
| 272 | ## Structs | |
| 273 | ||
| 274 | ~~~~{.rust} | |
| 275 | struct Point { x: f64, y: f64 } | |
| 276 | ||
| 277 | fn isOrigin1 (p: Point) -> bool { | |
| 278 | p.x == 0.0 && p.y == 0.0 | |
| 279 | } | |
| 280 | ~~~~ | |
| 281 | ||
| 282 | ~~~~{.rust} | |
| 283 | fn isOrigin2 (p: Point) -> bool { | |
| 284 | match p { | |
| 285 | Point { x: 0.0, y: 0.0 } => true, | |
| 286 | _ => false | |
| 287 | } | |
| 288 | } | |
| 289 | ~~~~ | |
| 290 | ||
| 291 | # Basics of Rust | |
| 292 | ||
| 293 | ## Enums | |
| 294 | ||
| 295 | ~~~~{.rust} | |
| 296 | enum Color { Red, Green, Blue } | |
| 297 | ||
| 298 | enum Shape { | |
| 299 | Circle(Point, f64), | |
| 300 | Rectangle(Point, Point), | |
| 301 | } | |
| 302 | ||
| 303 | fn area(s: Shape) -> f64 { | |
| 304 | match s { | |
| 305 | Circle(_, sz) => f64::consts::pi * sz * sz, | |
| 306 | Rectangle(p1, p2) => (p2.x - p1.x) * (p2.y - p1.y) | |
| 307 | } | |
| 308 | } | |
| 309 | ~~~~ | |
| 310 | ||
| 311 | # Pointers and Memory | |
| 312 | ||
| 313 |
# |
|
| 192 | # What Makes Rust Interesting | |
| 193 | ||
| 194 | ## Ownership | |
| 314 | 195 | |
| 315 | 196 | \begin{center} |
| 316 | 197 | \includegraphics[width=.9\textwidth]{imgs/dawkins-owned.png} |
| 317 | 198 | \end{center} |
| 318 | 199 | |
| 200 | ## Ownership | |
| 201 | ||
| 202 | ~~~~{.rust} | |
| 203 | #[derive(Debug)] | |
| 204 | struct MyNum { num: i32 } | |
| 205 | ||
| 206 | fn main() { | |
| 207 | let x = MyNum { num: 2 }; | |
| 208 | println!("x = {:?}", x); | |
| 209 | } | |
| 210 | ~~~~ | |
| 211 | ||
| 212 | # Brief Aside | |
| 213 | ## Traits | |
| 214 | ||
| 215 | ~~~~{.rust} | |
| 216 | trait ToString { | |
| 217 | fn to_string(&self) -> String; | |
| 218 | } | |
| 219 | ||
| 220 | impl ToString for () { | |
| 221 | fn to_string(&self) -> String { | |
| 222 | "unit".to_owned() | |
| 223 | } | |
| 224 | } | |
| 225 | ~~~~ | |
| 226 | ||
| 227 | # Brief Aside | |
| 228 | ## Traits | |
| 229 | ||
| 230 | ~~~~{.rust} | |
| 231 | fn print_excitedly<T: ToString>(t: T) { | |
| 232 | println!("{}!!!", t.to_string()); | |
| 233 | } | |
| 234 | ||
| 235 | fn main() { | |
| 236 | print_excitedly( () ); | |
| 237 | } | |
| 238 | ~~~~ | |
| 239 | ||
| 240 | # Brief Aside from the Brief Aside | |
| 241 | ## Polymorphism | |
| 242 | ||
| 243 | ~~~~{.rust} | |
| 244 | fn make_pair<A, B>(a: A, b: B) -> (A, B) { | |
| 245 | (a, b) | |
| 246 | } | |
| 247 | ||
| 248 | fn not_eq<A: Eq>(left: A, right: A) -> bool { | |
| 249 | left != right | |
| 250 | } | |
| 251 | ~~~~ | |
| 252 | ||
| 253 | # Brief Aside from the Brief Aside | |
| 254 | ## Polymorphism | |
| 255 | ||
| 256 | ~~~~{.rust} | |
| 257 | fn print_eq<A: Eq + ToString>(left: A, right: A) { | |
| 258 | if left == right { | |
| 259 | println!("{} and {} are equal", | |
| 260 | left.to_string(), | |
| 261 | right.to_string()); | |
| 262 | } else { | |
| 263 | println!("{} and {} are different", | |
| 264 | left.to_string(), | |
| 265 | right.to_string()); | |
| 266 | } | |
| 267 | } | |
| 268 | ~~~~ | |
| 269 | ||
| 270 | # Brief Aside | |
| 271 | ## Traits | |
| 272 | ||
| 273 | ~~~~{.rust} | |
| 274 | /* this is /slightly/ different in the stdlib */ | |
| 275 | trait PartialEq<Rhs> { | |
| 276 | fn eq(&self, other: &Rhs) -> bool; | |
| 277 | fn ne(&self, other: &Rhs) -> bool; | |
| 278 | } | |
| 279 | ||
| 280 | /* no more methods, but more laws */ | |
| 281 | trait Eq: PartialEq<Self> { } | |
| 282 | ~~~~ | |
| 283 | ||
| 284 | # Brief Aside | |
| 285 | ## Traits | |
| 286 | ||
| 287 | ~~~~{.rust} | |
| 288 | struct MyNum { num: i32 } | |
| 289 | ||
| 290 | impl PartialEq<MyNum> for MyNum { | |
| 291 | fn eq(&self, other: &MyNum) -> bool { | |
| 292 | self.num == other.num | |
| 293 | } | |
| 294 | } | |
| 295 | ||
| 296 | impl Eq for MyNum { } | |
| 297 | ~~~~ | |
| 298 | ||
| 299 | # Brief Aside | |
| 300 | ## Traits | |
| 301 | ||
| 302 | ~~~~{.rust} | |
| 303 | /* or just this */ | |
| 304 | #[derive(PartialEq,Eq)] | |
| 305 | struct MyNum { num: i32 } | |
| 306 | ~~~~ | |
| 307 | ||
| 308 | # What Makes Rust Interesting | |
| 309 | ||
| 310 | ## Ownership | |
| 311 | ||
| 312 | ~~~~{.rust} | |
| 313 | #[derive(Debug)] | |
| 314 | struct MyNum { num: i32 } | |
| 315 | ||
| 316 | fn main() { | |
| 317 | let x = MyNum { num: 2 }; | |
| 318 | let y = x; | |
| 319 | println!("x = {:?}", x); | |
| 320 | ||
| 321 | } | |
| 322 | ~~~~ | |
| 323 | ||
| 324 | # What Makes Rust Interesting | |
| 325 | ||
| 326 | ## Ownership | |
| 327 | ||
| 328 | ~~~~{.rust} | |
| 329 | #[derive(Debug)] | |
| 330 | struct MyNum { num: i32 } | |
| 331 | ||
| 332 | fn main() { | |
| 333 | let x = MyNum { num: 2 }; | |
| 334 | let y = x; /* <- value moves here */ | |
| 335 | println!("x = {:?}", x); | |
| 336 | ||
| 337 | } | |
| 338 | ~~~~ | |
| 339 | ||
| 340 | # What Makes Rust Interesting | |
| 341 | ||
| 342 | ## Ownership | |
| 343 | ||
| 344 | ~~~~{.rust} | |
| 345 | #[derive(Debug)] | |
| 346 | struct MyNum { num: i32 } | |
| 347 | ||
| 348 | fn main() { | |
| 349 | let x = MyNum { num: 2 }; | |
| 350 | let y = x; | |
| 351 | println!("x = {:?}", x); | |
| 352 | /* so this does not compile */ | |
| 353 | } | |
| 354 | ~~~~ | |
| 355 | ||
| 356 | # What Makes Rust Interesting | |
| 357 | ||
| 358 | ## Ownership --- Explicit Cloning | |
| 359 | ||
| 360 | ~~~~{.rust} | |
| 361 | #[derive(Debug, Clone)] | |
| 362 | struct MyNum { num: i32 } | |
| 363 | ||
| 364 | fn main() { | |
| 365 | let x = MyNum { num: 2 }; | |
| 366 | let y = x.clone(); | |
| 367 | println!("x = {:?}", x); | |
| 368 | /* but this does! */ | |
| 369 | } | |
| 370 | ~~~~ | |
| 371 | ||
| 372 | # What Makes Rust Interesting | |
| 373 | ||
| 374 | ## Ownership --- Implicit Copying | |
| 375 | ||
| 376 | ~~~~{.rust} | |
| 377 | #[derive(Debug, Clone, Copy)] | |
| 378 | struct MyNum { num: i32 } | |
| 379 | ||
| 380 | fn main() { | |
| 381 | let x = MyNum { num: 2 }; | |
| 382 | let y = x; | |
| 383 | println!("x = {:?}", x); | |
| 384 | /* as does this! */ | |
| 385 | } | |
| 386 | ~~~~ | |
| 387 | ||
| 388 | # What Makes Rust Interesting | |
| 389 | ||
| 390 | ## Ownership --- Destructors | |
| 391 | ||
| 392 | ~~~~{.rust} | |
| 393 | #[derive(Debug)] | |
| 394 | struct MyNum { num: i32 } | |
| 395 | ||
| 396 | impl Drop for MyNum { | |
| 397 | fn drop(&mut self) { | |
| 398 | println!("dropping: {:?}", self) | |
| 399 | } | |
| 400 | } | |
| 401 | ||
| 402 | fn main() { | |
| 403 | let x = MyNum { num: 2 }; | |
| 404 | println!("x = {:?}", x); | |
| 405 | } | |
| 406 | ~~~~ | |
| 407 | ||
| 408 | # What Makes Rust Interesting | |
| 409 | ||
| 410 | ## Ownership --- Special Clones | |
| 411 | ||
| 412 | ~~~~{.rust} | |
| 413 | #[derive(Debug)] | |
| 414 | struct MyNum { num: i32 } | |
| 415 | ||
| 416 | impl Clone for MyNum { | |
| 417 | fn clone(&self) -> Self { | |
| 418 | println!("Cloning a MyNum..."); | |
| 419 | MyNum { num: self.num } | |
| 420 | } | |
| 421 | } | |
| 422 | ||
| 423 | fn main() { | |
| 424 | let x = MyNum { num: 2 }; | |
| 425 | let y = x.clone(); | |
| 426 | println!("x = {:?}", y); | |
| 427 | } | |
| 428 | ~~~~ | |
| 429 | ||
| 430 | # What Makes Rust Interesting | |
| 431 | ||
| 432 | ## References | |
| 433 | ||
| 434 | \begin{center} | |
| 435 | \includegraphics[width=.9\textwidth]{imgs/dril-owned.png} | |
| 436 | \end{center} | |
| 437 | ||
| 438 | # What Makes Rust Interesting | |
| 439 | ||
| 440 | ## References | |
| 441 | ||
| 442 | ~~~~{.rust} | |
| 443 | #[derive(Debug)] | |
| 444 | struct MyNum { num: i32 } | |
| 445 | ||
| 446 | fn some_func(_: MyNum) { | |
| 447 | println!("yeah, whatevs"); | |
| 448 | } | |
| 449 | ||
| 450 | fn main() { | |
| 451 | let x = MyNum { num: 2 }; | |
| 452 | some_func(x); | |
| 453 | println("{:?}", x); | |
| 454 | ||
| 455 | } | |
| 456 | ~~~~ | |
| 457 | ||
| 458 | # What Makes Rust Interesting | |
| 459 | ||
| 460 | ## References | |
| 461 | ||
| 462 | ~~~~{.rust} | |
| 463 | #[derive(Debug)] | |
| 464 | struct MyNum { num: i32 } | |
| 465 | ||
| 466 | fn some_func(_: MyNum) { | |
| 467 | println!("yeah, whatevs"); | |
| 468 | } | |
| 469 | ||
| 470 | fn main() { | |
| 471 | let x = MyNum { num: 2 }; | |
| 472 | some_func(x); | |
| 473 | println("{:?}", x); | |
| 474 | /* ERROR: use of moved value */ | |
| 475 | } | |
| 476 | ~~~~ | |
| 477 | ||
| 478 | # What Makes Rust Interesting | |
| 479 | ||
| 480 | ## References | |
| 481 | ||
| 482 | ~~~~{.rust} | |
| 483 | #[derive(Debug)] | |
| 484 | struct MyNum { num: i32 } | |
| 485 | ||
| 486 | fn some_func(_: MyNum) -> MyNum { | |
| 487 | println!("yeah, whatevs"); | |
| 488 | } | |
| 489 | ||
| 490 | fn main() { | |
| 491 | let x = MyNum { num: 2 }; | |
| 492 | let y = some_func(x.clone()); | |
| 493 | println("{:?}", y); | |
| 494 | /* works---but so tedious! */ | |
| 495 | } | |
| 496 | ~~~~ | |
| 497 | ||
| 498 | # What Makes Rust Interesting | |
| 499 | ||
| 500 | ## References | |
| 501 | ||
| 502 | ~~~~{.rust} | |
| 503 | #[derive(Debug,Clone)] | |
| 504 | struct MyNum { num: i32 } | |
| 505 | ||
| 506 | fn some_func(_: MyNum) { | |
| 507 | println!("yeah, whatevs"); | |
| 508 | } | |
| 509 | ||
| 510 | fn main() { | |
| 511 | let x = MyNum { num: 2 }; | |
| 512 | some_func(x.clone()); | |
| 513 | println("{:?}", x); | |
| 514 | /* works---but not what we want */ | |
| 515 | } | |
| 516 | ~~~~ | |
| 517 | ||
| 518 | # What Makes Rust Interesting | |
| 519 | ||
| 520 | ## References | |
| 521 | ||
| 522 | ~~~~{.rust} | |
| 523 | #[derive(Debug,Clone)] | |
| 524 | struct MyNum { num: i32 } | |
| 525 | ||
| 526 | fn some_func(_: &MyNum) { | |
| 527 | println!("yeah, whatevs"); | |
| 528 | } | |
| 529 | ||
| 530 | fn main() { | |
| 531 | let x = MyNum { num: 2 }; | |
| 532 | some_func(&x); | |
| 533 | println("{:?}", x); | |
| 534 | /* works! */ | |
| 535 | } | |
| 536 | ~~~~ | |
| 537 | ||
| 538 | # Pointers and Memory | |
| 539 | ||
| 319 | 540 | # Pointers and Memory |
| 320 | 541 | |
| 321 | 542 | ## "Owned" Pointers |
| 322 | 543 | |
| 323 | 544 | ~~~~{.rust} |
| 324 | 545 | fn main() { |
| 325 |
let x: |
|
| 546 | let x: Box<[i32]> = Box::new([1,2,3]); | |
| 326 | 547 | /* x in scope */ |
| 327 | 548 | { |
| 328 |
let y: |
|
| 549 | let y: Box<[i32]> = Box::new([4,5,6]); | |
| 329 | 550 | /* x, y in scope */ |
| 330 | 551 | } |
| 331 | 552 | /* x in scope */ |
| 338 | 559 | |
| 339 | 560 | ~~~~{.rust} |
| 340 | 561 | fn main() { |
| 341 | let x: ~[int] = ~[1,2,3]; // malloc |----+ | |
| 342 | /* ... */ // | | |
| 343 | { // | | |
| 344 | let y: ~[int] = ~[4,5,6]; // malloc |-+ | | |
| 345 | /* ... */ // | | | |
| 346 | } // free <---+ | | |
| 347 | /* ... */ // | | |
| 348 | } // free <------+ | |
| 562 | let x: Box<[i32]> = // malloc |----+ | |
| 563 | Box::new([1,2,3]); // | | |
| 564 | /* ... */ // | | |
| 565 | { // | | |
| 566 | let y: Box<[i32]> = // malloc |-+ | | |
| 567 | Box::new([4,5,6]); // | | | |
| 568 | /* ... */ // | | | |
| 569 | } // free <---+ | | |
| 570 | /* ... */ // | | |
| 571 | } // free <------+ | |
| 349 | 572 | ~~~~ |
| 350 | 573 | |
| 351 | 574 | # Pointers and Memory |
| 353 | 576 | ## "Owned" Pointers |
| 354 | 577 | |
| 355 | 578 | ~~~~{.rust} |
| 356 | fn f0() -> ~[int] { | |
| 357 | return ~[1,2,3]; // returning ownership | |
| 358 | } | |
| 359 | fn f1() -> ~[int] { | |
| 360 | let a = ~[1,2,3]; | |
| 579 | fn f0() -> Box<[i32]> { | |
| 580 | return Box::new([1,2,3]); // returning ownership | |
| 581 | } | |
| 582 | fn f1() -> Box<[int]> { | |
| 583 | let a = Box::new([1,2,3]); | |
| 361 | 584 | let b = a; |
| 362 | 585 | return a; // error: use of moved value: `a` |
| 363 | 586 | } |
| 364 | fn f2() -> ~[int] { | |
| 365 | let a = ~[1,2,3]; | |
| 587 | fn f2() -> Box::new([int]) { | |
| 588 | let a = Box::new([1,2,3]); | |
| 366 | 589 | let b = a.clone(); |
| 367 | 590 | return a; // fine now; `a` and `b` both valid |
| 368 | 591 | } |
| 376 | 599 | #[deriving(Clone)] |
| 377 | 600 | enum List<T> { Cons(T, ~List<T>), Nil } |
| 378 | 601 | |
| 379 | fn f3() -> ~List<int> { | |
| 380 | let mut a = ~Cons(1, ~Cons(2, ~Nil)) | |
| 602 | fn f3() -> Box<List<int>> { | |
| 603 | let mut a = Box::new(Cons(1, | |
| 604 | Box::new(Cons(2, Box::new(Nil))))); | |
| 381 | 605 | /* a is mutable */ |
| 382 | 606 | let b = a; |
| 383 | 607 | /* can no longer use a, b is immutable */ |
| 394 | 618 | ~~~~{.rust} |
| 395 | 619 | type t8 = (u32,u32,u32,u32,u32,u32,u32,u32); |
| 396 | 620 | |
| 397 | fn eight_nums() -> ~t8 { | |
| 398 | ~(1,2,3,4,5,6,7,8) | |
| 399 | } | |
| 400 | ||
| 401 | fn main() { | |
| 402 | let t: ~t8 = eight_nums(); | |
| 621 | fn eight_nums() -> Box<t8> { | |
| 622 | Box::new((1,2,3,4,5,6,7,8)) | |
| 623 | } | |
| 624 | ||
| 625 | fn main() { | |
| 626 | let t: Box<t8> = eight_nums(); | |
| 403 | 627 | /* ... */ |
| 404 | 628 | } |
| 405 | 629 | ~~~~ |
| 416 | 640 | } |
| 417 | 641 | |
| 418 | 642 | fn main() { |
| 419 |
let t: |
|
| 643 | let t: Box<t8> = Box::new(eight_nums()); | |
| 420 | 644 | /* ... */ |
| 421 | 645 | } |
| 422 | 646 | ~~~~ |