deleted older slide material
Getty Ritter
10 years ago
| 534 | 534 | /* works! */ |
| 535 | 535 | } |
| 536 | 536 | ~~~~ |
| 537 | ||
| 538 | # Pointers and Memory | |
| 539 | ||
| 540 | # Pointers and Memory | |
| 541 | ||
| 542 | ## "Owned" Pointers | |
| 543 | ||
| 544 | ~~~~{.rust} | |
| 545 | fn main() { | |
| 546 | let x: Box<[i32]> = Box::new([1,2,3]); | |
| 547 | /* x in scope */ | |
| 548 | { | |
| 549 | let y: Box<[i32]> = Box::new([4,5,6]); | |
| 550 | /* x, y in scope */ | |
| 551 | } | |
| 552 | /* x in scope */ | |
| 553 | } | |
| 554 | ~~~~ | |
| 555 | ||
| 556 | # Pointers and Memory | |
| 557 | ||
| 558 | ## "Owned" Pointers | |
| 559 | ||
| 560 | ~~~~{.rust} | |
| 561 | fn main() { | |
| 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 <------+ | |
| 572 | ~~~~ | |
| 573 | ||
| 574 | # Pointers and Memory | |
| 575 | ||
| 576 | ## "Owned" Pointers | |
| 577 | ||
| 578 | ~~~~{.rust} | |
| 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]); | |
| 584 | let b = a; | |
| 585 | return a; // error: use of moved value: `a` | |
| 586 | } | |
| 587 | fn f2() -> Box::new([int]) { | |
| 588 | let a = Box::new([1,2,3]); | |
| 589 | let b = a.clone(); | |
| 590 | return a; // fine now; `a` and `b` both valid | |
| 591 | } | |
| 592 | ~~~~ | |
| 593 | ||
| 594 | # Pointers and Memory | |
| 595 | ||
| 596 | ## "Owned" Pointers | |
| 597 | ||
| 598 | ~~~~{.rust} | |
| 599 | #[deriving(Clone)] | |
| 600 | enum List<T> { Cons(T, ~List<T>), Nil } | |
| 601 | ||
| 602 | fn f3() -> Box<List<int>> { | |
| 603 | let mut a = Box::new(Cons(1, | |
| 604 | Box::new(Cons(2, Box::new(Nil))))); | |
| 605 | /* a is mutable */ | |
| 606 | let b = a; | |
| 607 | /* can no longer use a, b is immutable */ | |
| 608 | let mut c = b.clone(); | |
| 609 | /* can use both b and c */ | |
| 610 | return b; | |
| 611 | } | |
| 612 | ~~~~ | |
| 613 | ||
| 614 | # Pointers and Memory | |
| 615 | ||
| 616 | ## Dispreferred Style | |
| 617 | ||
| 618 | ~~~~{.rust} | |
| 619 | type t8 = (u32,u32,u32,u32,u32,u32,u32,u32); | |
| 620 | ||
| 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(); | |
| 627 | /* ... */ | |
| 628 | } | |
| 629 | ~~~~ | |
| 630 | ||
| 631 | # Pointers and Memory | |
| 632 | ||
| 633 | ## Preferred Style | |
| 634 | ||
| 635 | ~~~~{.rust} | |
| 636 | type t8 = (u32,u32,u32,u32,u32,u32,u32,u32); | |
| 637 | ||
| 638 | fn eight_nums() -> t8 { | |
| 639 | (1,2,3,4,5,6,7,8) | |
| 640 | } | |
| 641 | ||
| 642 | fn main() { | |
| 643 | let t: Box<t8> = Box::new(eight_nums()); | |
| 644 | /* ... */ | |
| 645 | } | |
| 646 | ~~~~ | |
| 647 | ||
| 648 | # Pointers and Memory | |
| 649 | ||
| 650 | ## References | |
| 651 | ||
| 652 | ~~~~{.rust} | |
| 653 | { | |
| 654 | let p = Point { x: 1.2, y: 3.4 }; | |
| 655 | let q = & p; | |
| 656 | // both p and q usable | |
| 657 | } | |
| 658 | { | |
| 659 | let q = & Point { x: 1.2, y: 3.4 }; | |
| 660 | } | |
| 661 | { | |
| 662 | let p = Point { x: 1.2, y: 3.4 }; | |
| 663 | let r = & p.x; | |
| 664 | } | |
| 665 | ~~~~ | |
| 666 | ||
| 667 | # Pointers and Memory | |
| 668 | ||
| 669 | ## References | |
| 670 | ||
| 671 | ~~~~{.rust} | |
| 672 | fn eq(xl: ~List<int>, yl: ~List<int>) -> bool { | |
| 673 | /* elided */ | |
| 674 | } | |
| 675 | ||
| 676 | fn main() { | |
| 677 | let l1 = ~Cons(1, ~Cons (2, ~Nil)); | |
| 678 | let l2 = ~Cons(3, ~Cons (4, ~Nil)); | |
| 679 | println!("{}", eq(l1, l2)); | |
| 680 | println!("{:?}", l1); | |
| 681 | } | |
| 682 | ~~~~ | |
| 683 | ||
| 684 | # Pointers and Memory | |
| 685 | ||
| 686 | ## References | |
| 687 | ||
| 688 | ~~~~{.rust} | |
| 689 | fn eq(xl: ~List<int>, yl: ~List<int>) -> bool { | |
| 690 | /* elided */ | |
| 691 | } | |
| 692 | ||
| 693 | fn main() { | |
| 694 | let l1 = ~Cons(1, ~Cons (2, ~Nil)); | |
| 695 | let l2 = ~Cons(3, ~Cons (4, ~Nil)); | |
| 696 | println!("{}", eq(l1, l2)); // ownership of l1 and l2 | |
| 697 | // moves to eq function | |
| 698 | println!("{:?}", l1); // error: use of moved value! | |
| 699 | } | |
| 700 | ~~~~ | |
| 701 | ||
| 702 | # Pointers and Memory | |
| 703 | ||
| 704 | ## References | |
| 705 | ||
| 706 | ~~~~{.rust} | |
| 707 | fn eq(xl: ~List<int>, yl: ~List<int>) -> bool { | |
| 708 | /* elided */ | |
| 709 | } | |
| 710 | ||
| 711 | fn main() { | |
| 712 | let l1 = ~Cons(1, ~Cons (2, ~Nil)); | |
| 713 | let l2 = ~Cons(3, ~Cons (4, ~Nil)); | |
| 714 | println!("{}", eq(l1.clone(), l2.clone())); | |
| 715 | println!("{:?}", l1); | |
| 716 | } | |
| 717 | ~~~~ | |
| 718 | ||
| 719 | # Pointers and Memory | |
| 720 | ||
| 721 | ## References | |
| 722 | ||
| 723 | ~~~~{.rust} | |
| 724 | fn eq(xl: &List<int>, yl: &List<int>) -> bool { | |
| 725 | /* elided */ | |
| 726 | } | |
| 727 | ||
| 728 | fn main() { | |
| 729 | let l1 = ~Cons(1, ~Cons (2, ~Nil)); | |
| 730 | let l2 = ~Cons(3, ~Cons (4, ~Nil)); | |
| 731 | println!("{}", eq(l1, l2)); | |
| 732 | println!("{:?}", l1); | |
| 733 | } | |
| 734 | ~~~~ | |
| 735 | ||
| 736 | # Pointers and Memory | |
| 737 | ||
| 738 | ## References | |
| 739 | ||
| 740 | ~~~~{.rust} | |
| 741 | fn eq(xl: &List<int>, yl: &List<int>) -> bool { | |
| 742 | match (xl, yl) { | |
| 743 | (&Nil, &Nil) => true, | |
| 744 | (&Cons(x, ~ref xs), &Cons(y, ~ref ys)) | |
| 745 | if x == y => eq(xs, ys), | |
| 746 | (_, _) => false | |
| 747 | } | |
| 748 | } | |
| 749 | ~~~~ | |
| 750 | ||
| 751 | # Pointers and Memory | |
| 752 | ||
| 753 | ## References | |
| 754 | ||
| 755 | ~~~~{.rust} | |
| 756 | fn eq<T: Eq>(xl: &List<T>, yl: &List<T>) -> bool { | |
| 757 | match (xl, yl) { | |
| 758 | (&Nil, &Nil) => true, | |
| 759 | (&Cons(x, ~ref xs), &Cons(y, ~ref ys)) | |
| 760 | if x == y => eq(xs, ys), | |
| 761 | (_, _) => false | |
| 762 | } | |
| 763 | } | |
| 764 | ~~~~ | |
| 765 | ||
| 766 | # Pointers and Memory | |
| 767 | ||
| 768 | ## References and Lifetimes | |
| 769 | ||
| 770 | ~~~~{.rust} | |
| 771 | { | |
| 772 | let a = ~5; | |
| 773 | let mut p = &a; | |
| 774 | { | |
| 775 | let b = ~8; | |
| 776 | p = &b; | |
| 777 | } | |
| 778 | println!("{}", **p) | |
| 779 | } | |
| 780 | ~~~~ | |
| 781 | ||
| 782 | ||
| 783 | # Pointers and Memory | |
| 784 | ||
| 785 | ## References and Lifetimes | |
| 786 | ||
| 787 | ~~~~{.rust} | |
| 788 | { | |
| 789 | let a = ~5; // malloc |---+ | |
| 790 | let mut p = &a; // | | |
| 791 | { // | | |
| 792 | let b = ~8; // malloc |-+ | | |
| 793 | p = &b; // | | | |
| 794 | } // free <---+ | | |
| 795 | println!("{}", **p) // | | |
| 796 | } // free <-----+ | |
| 797 | ~~~~ | |
| 798 | ||
| 799 | ||
| 800 | # Pointers and Memory | |
| 801 | ||
| 802 | ## References and Lifetimes | |
| 803 | ||
| 804 | ~~~~{.rust} | |
| 805 | { | |
| 806 | let a = ~5; | |
| 807 | let mut p = &a; | |
| 808 | { | |
| 809 | let b = ~8; | |
| 810 | p = &b; // error: borrowed value does | |
| 811 | // not live long enough | |
| 812 | } | |
| 813 | println!("{}", **p) | |
| 814 | } | |
| 815 | ~~~~ | |
| 816 | # Pointers and Memory | |
| 817 | ||
| 818 | ## References, Pointers, Mutability | |
| 819 | ||
| 820 | ~~~~{.rust} | |
| 821 | { | |
| 822 | let mut x = ~5; | |
| 823 | *x = *x + 1; | |
| 824 | { | |
| 825 | let y = &x; | |
| 826 | /* x is not mutable for the rest of this block */ | |
| 827 | } | |
| 828 | /* x regains mutability */ | |
| 829 | } | |
| 830 | ~~~~ | |
| 831 | ||
| 832 | # Pointers and Memory | |
| 833 | ||
| 834 | ## References, Pointers, Mutability | |
| 835 | ||
| 836 | ~~~~{.rust} | |
| 837 | enum IntList { | |
| 838 | Cons { head: int, tail: ~IntList }, | |
| 839 | Nil, | |
| 840 | } | |
| 841 | { | |
| 842 | let mut lst = ~Cons { head: 5, tail: ~Nil }; | |
| 843 | { | |
| 844 | let y = &(lst.head); // or &((*lst).head) | |
| 845 | lst = ~Nil; | |
| 846 | println!("{}", y); | |
| 847 | } | |
| 848 | } | |
| 849 | ~~~~ | |
| 850 | ||
| 851 | # Pointers and Memory | |
| 852 | ||
| 853 | ## References, Pointers, Mutability | |
| 854 | ||
| 855 | ~~~~{.rust} | |
| 856 | enum IntList { | |
| 857 | Cons { head: int, tail: ~IntList }, | |
| 858 | Nil, | |
| 859 | } | |
| 860 | { | |
| 861 | let mut lst = ~Cons { head: 5, tail: ~Nil }; | |
| 862 | { | |
| 863 | let y = &(lst.head); | |
| 864 | lst = ~Nil; | |
| 865 | println!("{}", y); // BAD | |
| 866 | } | |
| 867 | } | |
| 868 | ~~~~ | |
| 869 | ||
| 870 | # Pointers and Memory | |
| 871 | ||
| 872 | ## Named Lifetimes | |
| 873 | ||
| 874 | ~~~~{.rust} | |
| 875 | fn tail<T>(lst: &List<T>) -> &List<T> { | |
| 876 | match *lst { | |
| 877 | Nil => &Nil, | |
| 878 | Cons(_, ~ref xs) => xs | |
| 879 | } | |
| 880 | } | |
| 881 | ~~~~ | |
| 882 | ||
| 883 | # Pointers and Memory | |
| 884 | ||
| 885 | ## Named Lifetimes | |
| 886 | ||
| 887 | ~~~~{.rust} | |
| 888 | fn tail<'s, T>(lst: &'s List<T>) -> &'s List<T> { | |
| 889 | match *lst { | |
| 890 | Nil => &Nil, | |
| 891 | Cons(_, ~ref xs) => xs | |
| 892 | } | |
| 893 | } | |
| 894 | ~~~~ | |
| 895 | ||
| 896 | # Pointers and Memory | |
| 897 | ||
| 898 | ## Reference Counting | |
| 899 | ||
| 900 | ~~~~{.rust} | |
| 901 | use std::rc::Rc; | |
| 902 | { | |
| 903 | let x = Rc::new([1,2,3]); | |
| 904 | let y = x.clone(); // two references, one vector | |
| 905 | assert!(x.ptr_eq(y)); | |
| 906 | assert!(*y.borrow() == [1,2,3]); | |
| 907 | } | |
| 908 | ~~~~ | |
| 909 | ||
| 910 | ## Garbage Collection | |
| 911 | ||
| 912 | ~~~~{.rust} | |
| 913 | use std::gc::Gc; | |
| 914 | { | |
| 915 | let x = Gc::new([1,2,3]); | |
| 916 | // etc. | |
| 917 | } | |
| 918 | ~~~~ | |
| 919 | ||
| 920 | # Pointers and Memory | |
| 921 | ||
| 922 | ## C Pointers | |
| 923 | ||
| 924 | ~~~~{.rust} | |
| 925 | use std::ptr::RawPtr; | |
| 926 | ||
| 927 | #[link(name="foo")] | |
| 928 | extern { | |
| 929 | fn unsafe_get() -> *int; | |
| 930 | } | |
| 931 | ||
| 932 | fn safe_get() -> Option<int> { | |
| 933 | unsafe { | |
| 934 | let i = unsafe_get(); | |
| 935 | i.to_option() | |
| 936 | } | |
| 937 | } | |
| 938 | ~~~~ | |
| 939 | ||
| 940 | # Closures | |
| 941 | ||
| 942 | # Closures | |
| 943 | ||
| 944 | > [...] Lambdas are relegated to relative obscurity until Java makes them | |
| 945 | > popular by not having them. | |
| 946 | > | |
| 947 | > —James Iry, "A Brief, Incomplete, and Mostly Wrong History of Programming | |
| 948 | > Languages" | |
| 949 | ||
| 950 | # Closures | |
| 951 | ||
| 952 | ## Functions | |
| 953 | ||
| 954 | ~~~~{.rust} | |
| 955 | fn main() { | |
| 956 | let x = 5; | |
| 957 | fn inner(y: int) -> int { | |
| 958 | return x + y; | |
| 959 | } | |
| 960 | println!("{}", inner(1)); | |
| 961 | } | |
| 962 | ~~~~ | |
| 963 | ||
| 964 | # Closures | |
| 965 | ||
| 966 | ## Functions Do NOT Close Over Env | |
| 967 | ||
| 968 | ~~~~{.rust} | |
| 969 | fn main() { | |
| 970 | let x = 5; | |
| 971 | fn inner(y: int) -> int { | |
| 972 | return x + y; // error: can't capture dynamic env | |
| 973 | } | |
| 974 | println!("{}", inner(1)); | |
| 975 | } | |
| 976 | ~~~~ | |
| 977 | ||
| 978 | # Closures | |
| 979 | ||
| 980 | ## Stack Closure | |
| 981 | ||
| 982 | ~~~~{.rust} | |
| 983 | fn main() { | |
| 984 | let x = 5; | |
| 985 | let inner = |y| x + y; | |
| 986 | println!("{}", inner(1)); | |
| 987 | } | |
| 988 | ~~~~ | |
| 989 | ||
| 990 | ## Stack Closure with Type Annotations | |
| 991 | ||
| 992 | ~~~~{.rust} | |
| 993 | fn main() { | |
| 994 | let x = 5; | |
| 995 | let inner = |y: int| -> int { x + y }; | |
| 996 | println!("{}", inner(1)); | |
| 997 | } | |
| 998 | ~~~~ | |
| 999 | ||
| 1000 | # Closures | |
| 1001 | ||
| 1002 | ## Stack Closures | |
| 1003 | ||
| 1004 | ~~~~{.rust} | |
| 1005 | fn my_map<A,B>(f: |&A|->B, l: &List<A>) -> List<B> { | |
| 1006 | match *l { | |
| 1007 | Nil => Nil, | |
| 1008 | Cons(ref x, ~ref xs) => | |
| 1009 | Cons(f(x)), ~my_map(f, xs)) | |
| 1010 | } | |
| 1011 | } | |
| 1012 | ||
| 1013 | fn main() { | |
| 1014 | fn incr(x: &int) -> int { x + 1 } | |
| 1015 | let l = ~Cons(1, ~Cons(2, ~Cons(3, ~Nil))); | |
| 1016 | println!("{:?}", my_map(|x| x + 1, l)); | |
| 1017 | println!("{:?}", my_map(incr, l)); | |
| 1018 | } | |
| 1019 | ~~~~ | |
| 1020 | ||
| 1021 | # Closures | |
| 1022 | ||
| 1023 | ## Owned Closures | |
| 1024 | ||
| 1025 | ~~~~{.rust} | |
| 1026 | use std::task::spawn; | |
| 1027 | ||
| 1028 | fn main() { | |
| 1029 | let x = ~5; | |
| 1030 | spawn(proc() { | |
| 1031 | println!("{}", x); | |
| 1032 | }); | |
| 1033 | // x is now owned by the proc above | |
| 1034 | } | |
| 1035 | ~~~~ | |
| 1036 | ||
| 1037 | # Methods | |
| 1038 | ||
| 1039 | ## Methods on a Struct | |
| 1040 | ||
| 1041 | ~~~~{.rust} | |
| 1042 | use std::f64::{sqrt,pow}; | |
| 1043 | struct Point { x: f64, y: f64 } | |
| 1044 | impl Point { | |
| 1045 | fn magnitude(&self) -> f64 { | |
| 1046 | sqrt(pow(self.x,2.0)+pow(self.y,2.0)) | |
| 1047 | } | |
| 1048 | fn new((my_x, my_y): (f64, f64)) -> Point { | |
| 1049 | Point { x: my_x, y: my_y } | |
| 1050 | } | |
| 1051 | } | |
| 1052 | fn main() { | |
| 1053 | let p = Point::new((2.0,4.0)); | |
| 1054 | println!("{}", p.magnitude()); | |
| 1055 | } | |
| 1056 | ~~~~ | |
| 1057 | ||
| 1058 | # Methods | |
| 1059 | ||
| 1060 | ## Methods on an Enum | |
| 1061 | ||
| 1062 | ~~~~{.rust} | |
| 1063 | impl<T> List<T> { | |
| 1064 | fn is_empty(&self) -> bool { | |
| 1065 | match self { | |
| 1066 | &Nil => true, | |
| 1067 | &Cons(_, _) => false, | |
| 1068 | } | |
| 1069 | } | |
| 1070 | } | |
| 1071 | ~~~~ | |
| 1072 | ||
| 1073 | # Traits | |
| 1074 | ||
| 1075 | ## Head of a List By Reference | |
| 1076 | ~~~~{.rust} | |
| 1077 | fn head<'a, T>(lst: &'a List<T>) -> Option<&'a T> { | |
| 1078 | match lst { | |
| 1079 | &Nil => None, | |
| 1080 | &Cons(ref hd, _) => Some(hd) | |
| 1081 | } | |
| 1082 | } | |
| 1083 | ~~~~ | |
| 1084 | ||
| 1085 | # Traits | |
| 1086 | ||
| 1087 | ## Head of a List By Value | |
| 1088 | ~~~~{.rust} | |
| 1089 | fn head<T>(lst: &List<T>) -> Option<T> { | |
| 1090 | match lst { | |
| 1091 | &Nil => None, | |
| 1092 | &Cons(ref hd, _) => Some(*hd) | |
| 1093 | } | |
| 1094 | } | |
| 1095 | ~~~~ | |
| 1096 | ||
| 1097 | # Traits | |
| 1098 | ||
| 1099 | ## Head of a List By Value | |
| 1100 | ~~~~{.rust} | |
| 1101 | fn head<T>(lst: &List<T>) -> Option<T> { | |
| 1102 | match lst { | |
| 1103 | &Nil => None, | |
| 1104 | &Cons(ref hd, _) => Some(*hd) | |
| 1105 | // cannot move out of dereference of & pointer | |
| 1106 | } | |
| 1107 | } | |
| 1108 | ~~~~ | |
| 1109 | ||
| 1110 | # Traits | |
| 1111 | ||
| 1112 | ## Head of a List By Value | |
| 1113 | ~~~~{.rust} | |
| 1114 | fn head<T: Clone>(lst: &List<T>) -> Option<T> { | |
| 1115 | match lst { | |
| 1116 | &Nil => None, | |
| 1117 | &Cons(ref hd, _) => Some(hd.clone()) | |
| 1118 | } | |
| 1119 | } | |
| 1120 | ~~~~ | |
| 1121 | ||
| 1122 | # Traits | |
| 1123 | ||
| 1124 | ## Declaring Traits | |
| 1125 | ~~~~{.rust} | |
| 1126 | trait Printable { | |
| 1127 | fn print(&self); | |
| 1128 | } | |
| 1129 | ||
| 1130 | impl Printable for int { | |
| 1131 | fn print(&self) { println!("{}", *self) } | |
| 1132 | } | |
| 1133 | ||
| 1134 | impl Printable for bool { | |
| 1135 | fn print(&self) { println!("{}", *self) } | |
| 1136 | } | |
| 1137 | ||
| 1138 | fn main() { | |
| 1139 | 5.print(); true.print(); | |
| 1140 | } | |
| 1141 | ~~~~ | |
| 1142 | ||
| 1143 | # Traits | |
| 1144 | ||
| 1145 | ## Using Multiple Traits | |
| 1146 | ||
| 1147 | ~~~~{.rust} | |
| 1148 | fn print_head<T: Clone+Printable>(lst: &List<T>) { | |
| 1149 | match lst { | |
| 1150 | &Nil => { println!("Nothing!") } | |
| 1151 | &Cons(ref hd, _) => { hd.clone().print() } | |
| 1152 | } | |
| 1153 | } | |
| 1154 | ~~~~ | |
| 1155 | ||
| 1156 | # Traits | |
| 1157 | ||
| 1158 | ## Static Dispatch | |
| 1159 | ||
| 1160 | ~~~~{.rust} | |
| 1161 | fn printAll<T: Printable>(vec: &[T]) { | |
| 1162 | for p in vec.iter() { p.print() } | |
| 1163 | } | |
| 1164 | fn main() { | |
| 1165 | printAll([1, 2, 3]); | |
| 1166 | } | |
| 1167 | ~~~~ | |
| 1168 | ||
| 1169 | ## Dynamic Dispatch | |
| 1170 | ||
| 1171 | ~~~~{.rust} | |
| 1172 | fn print_all(vec: &[~Printable]) { | |
| 1173 | for p in vec.iter() { p.print() } | |
| 1174 | } | |
| 1175 | fn main() { | |
| 1176 | print_all([~1 as ~Printable, ~true as ~Printable]); | |
| 1177 | } | |
| 1178 | ~~~~ | |
| 1179 | ||
| 1180 | # Tasks and Communication | |
| 1181 | ||
| 1182 | ## Tasks | |
| 1183 | ||
| 1184 | ~~~~{.rust} | |
| 1185 | fn main() { | |
| 1186 | spawn(proc() { | |
| 1187 | println!("Hello from another task!"); | |
| 1188 | }); | |
| 1189 | println!("Hello from the parent task!"); | |
| 1190 | } | |
| 1191 | ~~~~ | |
| 1192 | ||
| 1193 | # Tasks and Communication | |
| 1194 | ||
| 1195 | ## Communication | |
| 1196 | ||
| 1197 | ~~~~{.rust} | |
| 1198 | fn main() { | |
| 1199 | let (port, chan): (Port<int>, Chan<int>) = Chan::new(); | |
| 1200 | spawn(proc() { | |
| 1201 | chan.send(some_computation()); | |
| 1202 | }); | |
| 1203 | some_other_computation(); | |
| 1204 | let result = port.recv(); | |
| 1205 | } | |
| 1206 | ~~~~ | |
| 1207 | ||
| 1208 | # Tasks and Communication | |
| 1209 | ||
| 1210 | ## Atomic Reference Counting | |
| 1211 | ||
| 1212 | ~~~~{.rust} | |
| 1213 | fn main() { | |
| 1214 | let parent_copy = Arc::new(something_very_large()); | |
| 1215 | let (port, chan) = Chan::new(); | |
| 1216 | chan.send(parent_copy.clone()); | |
| 1217 | spawn(proc() { | |
| 1218 | let task_copy = port.recv(); | |
| 1219 | task_copy.get().do_something(); | |
| 1220 | }); | |
| 1221 | parent_copy.get().do_something_else(); | |
| 1222 | } | |
| 1223 | ~~~~ | |
| 1224 | ||
| 1225 | # Tasks and Communication | |
| 1226 | ||
| 1227 | ## Failure | |
| 1228 | ||
| 1229 | ~~~~{.rust} | |
| 1230 | fn main() { | |
| 1231 | let r : Result<int, ()> = try(proc() { | |
| 1232 | if some_operation_succeeds() { | |
| 1233 | return 5; | |
| 1234 | } else { | |
| 1235 | fail!("Hark! An error!"); | |
| 1236 | } | |
| 1237 | }); | |
| 1238 | match r { | |
| 1239 | Ok(i) => println!("Got {}", i), | |
| 1240 | Err(_) => println!("Hark!"), | |
| 1241 | }; | |
| 1242 | } | |
| 1243 | ~~~~ | |
| 1244 | ||
| 1245 | # Crates and Modules | |
| 1246 | ||
| 1247 | - A "crate" is a compilation unit; `rustc` produces a single crate | |
| 1248 | if it is run (either a library or an executable.) | |
| 1249 | - A module is a grouping of definitions. Modules can be hierarchical | |
| 1250 | and can be defined in a single file in `mod { ... }` blocks, or in | |
| 1251 | separate files. | |
| 1252 | ||
| 1253 | # Crates and Modules | |
| 1254 | ||
| 1255 | ## main.rs | |
| 1256 | ||
| 1257 | ~~~~{.rust} | |
| 1258 | mod mylist { | |
| 1259 | pub enum List<T> { Cons(T, ~List<T>), Nil } | |
| 1260 | pub fn from_vec<T>(mut vec : ~[T]) -> ~List<T> { ... } | |
| 1261 | impl<T> List<T> { | |
| 1262 | pub fn length(&self) -> int { ... } | |
| 1263 | } | |
| 1264 | } | |
| 1265 | ||
| 1266 | fn main() { | |
| 1267 | let v = ~[1,2,3]; | |
| 1268 | let l = ::mylist::from_vec(v); | |
| 1269 | /* ... */ | |
| 1270 | } | |
| 1271 | ~~~~ | |
| 1272 | ||
| 1273 | # Crates and Modules | |
| 1274 | ||
| 1275 | ## mylist.rs or mylist/mod.rs | |
| 1276 | ||
| 1277 | ~~~~{.rust} | |
| 1278 | mod mylist { | |
| 1279 | pub enum List<T> { Cons(T, ~List<T>), Nil } | |
| 1280 | pub fn from_vec<T>(mut vec : ~[T]) -> ~List<T> { ... } | |
| 1281 | impl<T> List<T> { | |
| 1282 | pub fn length(&self) -> int { ... } | |
| 1283 | } | |
| 1284 | } | |
| 1285 | ~~~~ | |
| 1286 | ||
| 1287 | ## main.rs | |
| 1288 | ||
| 1289 | ~~~~{.rust} | |
| 1290 | mod mylist; | |
| 1291 | main() { | |
| 1292 | let v = ~[1,2,3]; | |
| 1293 | let l = ::mylist::from_vec(v); | |
| 1294 | /* ... */ | |
| 1295 | } | |
| 1296 | ~~~~ | |
| 1297 | ||
| 1298 | # Crates and Modules | |
| 1299 | ## main.rs | |
| 1300 | ||
| 1301 | ~~~~{.rust} | |
| 1302 | use mylist::from_vec; | |
| 1303 | mod mylist; | |
| 1304 | ||
| 1305 | main() { | |
| 1306 | let v = ~[1,2,3]; | |
| 1307 | let l = from_vec(v); | |
| 1308 | /* ... */ | |
| 1309 | } | |
| 1310 | ~~~~ | |
| 1311 | ||
| 1312 | # Crates and Modules | |
| 1313 | ## Crate Metadata | |
| 1314 | ||
| 1315 | ~~~~{.rust} | |
| 1316 | #[crate_id = "mycrate#1.2"]; | |
| 1317 | #[crate_type = "lib"]; | |
| 1318 | ~~~~ | |
| 1319 | ||
| 1320 | ## Requesting Crate Metadata | |
| 1321 | ||
| 1322 | ~~~~{.rust} | |
| 1323 | extern crate mycrate "mycrate#1.2"; | |
| 1324 | extern crate oldmycrate "mycrate#0.6"; | |
| 1325 | ~~~~ | |
| 1326 | ||
| 1327 | # The Future | |
| 1328 | ||
| 1329 | # The Future | |
| 1330 | ||
| 1331 | \begin{center} | |
| 1332 | \includegraphics[width=.9\textwidth]{imgs/flying-machines.jpg} | |
| 1333 | \end{center} | |
| 1334 | ||
| 1335 | # The Future | |
| 1336 | ||
| 1337 | ## Possible Syntax Changes | |
| 1338 | ||
| 1339 | - `~foo` might become `box foo` | |
| 1340 | - `~[T]` might become `Vec<T>` | |
| 1341 | - Operator overloading | |
| 1342 | ||
| 1343 | ## Possible Language Changes | |
| 1344 | ||
| 1345 | - Speculations about inheritance, subtyping | |
| 1346 | - Stronger restrictions on `unsafe` code | |
| 1347 | ||
| 1348 | ## Standard Library Improvements | |
| 1349 | ||
| 1350 | ## Package Manager |