@@ -630,7 +630,7 @@ unsafe fn bump_levels_unsafe2() -> u32 {
630
630
Mutable statics have the same restrictions as normal statics, except that the
631
631
type of the value is not required to ascribe to ` Sync ` .
632
632
633
- ### ` 'static ` lifetime elision
633
+ #### ` 'static ` lifetime elision
634
634
635
635
[ Unstable] Both constant and static declarations of reference types have
636
636
* implicit* ` 'static ` lifetimes unless an explicit lifetime is specified. As
@@ -676,3 +676,372 @@ const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = ..
676
676
// `Fn(&'static Foo, &'static Bar) -> &'static Baz`.
677
677
const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
678
678
```
679
+
680
+ ### Traits
681
+
682
+ A _ trait_ describes an abstract interface that types can
683
+ implement. This interface consists of associated items, which come in
684
+ three varieties:
685
+
686
+ - functions
687
+ - constants
688
+ - types
689
+
690
+ Associated functions whose first parameter is named ` self ` are called
691
+ methods and may be invoked using ` . ` notation (e.g., ` x.foo() ` ).
692
+
693
+ All traits define an implicit type parameter ` Self ` that refers to
694
+ "the type that is implementing this interface". Traits may also
695
+ contain additional type parameters. These type parameters (including
696
+ ` Self ` ) may be constrained by other traits and so forth as usual.
697
+
698
+ Trait bounds on ` Self ` are considered "supertraits". These are
699
+ required to be acyclic. Supertraits are somewhat different from other
700
+ constraints in that they affect what methods are available in the
701
+ vtable when the trait is used as a [ trait object] ( #trait-objects ) .
702
+
703
+ Traits are implemented for specific types through separate
704
+ [ implementations] ( #implementations ) .
705
+
706
+ Consider the following trait:
707
+
708
+ ```
709
+ # type Surface = i32;
710
+ # type BoundingBox = i32;
711
+ trait Shape {
712
+ fn draw(&self, Surface);
713
+ fn bounding_box(&self) -> BoundingBox;
714
+ }
715
+ ```
716
+
717
+ This defines a trait with two methods. All values that have
718
+ [ implementations] ( #implementations ) of this trait in scope can have their
719
+ ` draw ` and ` bounding_box ` methods called, using ` value.bounding_box() `
720
+ [ syntax] ( #method-call-expressions ) .
721
+
722
+ Traits can include default implementations of methods, as in:
723
+
724
+ ```
725
+ trait Foo {
726
+ fn bar(&self);
727
+ fn baz(&self) { println!("We called baz."); }
728
+ }
729
+ ```
730
+
731
+ Here the ` baz ` method has a default implementation, so types that implement
732
+ ` Foo ` need only implement ` bar ` . It is also possible for implementing types
733
+ to override a method that has a default implementation.
734
+
735
+ Type parameters can be specified for a trait to make it generic. These appear
736
+ after the trait name, using the same syntax used in [ generic
737
+ functions] ( #generic-functions ) .
738
+
739
+ ```
740
+ trait Seq<T> {
741
+ fn len(&self) -> u32;
742
+ fn elt_at(&self, n: u32) -> T;
743
+ fn iter<F>(&self, F) where F: Fn(T);
744
+ }
745
+ ```
746
+
747
+ It is also possible to define associated types for a trait. Consider the
748
+ following example of a ` Container ` trait. Notice how the type is available
749
+ for use in the method signatures:
750
+
751
+ ```
752
+ trait Container {
753
+ type E;
754
+ fn empty() -> Self;
755
+ fn insert(&mut self, Self::E);
756
+ }
757
+ ```
758
+
759
+ In order for a type to implement this trait, it must not only provide
760
+ implementations for every method, but it must specify the type ` E ` . Here's
761
+ an implementation of ` Container ` for the standard library type ` Vec ` :
762
+
763
+ ```
764
+ # trait Container {
765
+ # type E;
766
+ # fn empty() -> Self;
767
+ # fn insert(&mut self, Self::E);
768
+ # }
769
+ impl<T> Container for Vec<T> {
770
+ type E = T;
771
+ fn empty() -> Vec<T> { Vec::new() }
772
+ fn insert(&mut self, x: T) { self.push(x); }
773
+ }
774
+ ```
775
+
776
+ Generic functions may use traits as _ bounds_ on their type parameters. This
777
+ will have two effects:
778
+
779
+ - Only types that have the trait may instantiate the parameter.
780
+ - Within the generic function, the methods of the trait can be
781
+ called on values that have the parameter's type.
782
+
783
+ For example:
784
+
785
+ ```
786
+ # type Surface = i32;
787
+ # trait Shape { fn draw(&self, Surface); }
788
+ fn draw_twice<T: Shape>(surface: Surface, sh: T) {
789
+ sh.draw(surface);
790
+ sh.draw(surface);
791
+ }
792
+ ```
793
+
794
+ Traits also define a [ trait object] ( #trait-objects ) with the same
795
+ name as the trait. Values of this type are created by coercing from a
796
+ pointer of some specific type to a pointer of trait type. For example,
797
+ ` &T ` could be coerced to ` &Shape ` if ` T: Shape ` holds (and similarly
798
+ for ` Box<T> ` ). This coercion can either be implicit or
799
+ [ explicit] ( #type-cast-expressions ) . Here is an example of an explicit
800
+ coercion:
801
+
802
+ ```
803
+ trait Shape { }
804
+ impl Shape for i32 { }
805
+ let mycircle = 0i32;
806
+ let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
807
+ ```
808
+
809
+ The resulting value is a box containing the value that was cast, along with
810
+ information that identifies the methods of the implementation that was used.
811
+ Values with a trait type can have [ methods called] ( #method-call-expressions ) on
812
+ them, for any method in the trait, and can be used to instantiate type
813
+ parameters that are bounded by the trait.
814
+
815
+ Trait methods may be static, which means that they lack a ` self ` argument.
816
+ This means that they can only be called with function call syntax (` f(x) ` ) and
817
+ not method call syntax (` obj.f() ` ). The way to refer to the name of a static
818
+ method is to qualify it with the trait name, treating the trait name like a
819
+ module. For example:
820
+
821
+ ```
822
+ trait Num {
823
+ fn from_i32(n: i32) -> Self;
824
+ }
825
+ impl Num for f64 {
826
+ fn from_i32(n: i32) -> f64 { n as f64 }
827
+ }
828
+ let x: f64 = Num::from_i32(42);
829
+ ```
830
+
831
+ Traits may inherit from other traits. Consider the following example:
832
+
833
+ ```
834
+ trait Shape { fn area(&self) -> f64; }
835
+ trait Circle : Shape { fn radius(&self) -> f64; }
836
+ ```
837
+
838
+ The syntax ` Circle : Shape ` means that types that implement ` Circle ` must also
839
+ have an implementation for ` Shape ` . Multiple supertraits are separated by ` + ` ,
840
+ ` trait Circle : Shape + PartialEq { } ` . In an implementation of ` Circle ` for a
841
+ given type ` T ` , methods can refer to ` Shape ` methods, since the typechecker
842
+ checks that any type with an implementation of ` Circle ` also has an
843
+ implementation of ` Shape ` :
844
+
845
+ ``` rust
846
+ struct Foo ;
847
+
848
+ trait Shape { fn area (& self ) -> f64 ; }
849
+ trait Circle : Shape { fn radius (& self ) -> f64 ; }
850
+ impl Shape for Foo {
851
+ fn area (& self ) -> f64 {
852
+ 0.0
853
+ }
854
+ }
855
+ impl Circle for Foo {
856
+ fn radius (& self ) -> f64 {
857
+ println! (" calling area: {}" , self . area ());
858
+
859
+ 0.0
860
+ }
861
+ }
862
+
863
+ let c = Foo ;
864
+ c . radius ();
865
+ ```
866
+
867
+ In type-parameterized functions, methods of the supertrait may be called on
868
+ values of subtrait-bound type parameters. Referring to the previous example of
869
+ ` trait Circle : Shape ` :
870
+
871
+ ```
872
+ # trait Shape { fn area(&self) -> f64; }
873
+ # trait Circle : Shape { fn radius(&self) -> f64; }
874
+ fn radius_times_area<T: Circle>(c: T) -> f64 {
875
+ // `c` is both a Circle and a Shape
876
+ c.radius() * c.area()
877
+ }
878
+ ```
879
+
880
+ Likewise, supertrait methods may also be called on trait objects.
881
+
882
+ ``` {.ignore}
883
+ # trait Shape { fn area(&self) -> f64; }
884
+ # trait Circle : Shape { fn radius(&self) -> f64; }
885
+ # impl Shape for i32 { fn area(&self) -> f64 { 0.0 } }
886
+ # impl Circle for i32 { fn radius(&self) -> f64 { 0.0 } }
887
+ # let mycircle = 0i32;
888
+ let mycircle = Box::new(mycircle) as Box<Circle>;
889
+ let nonsense = mycircle.radius() * mycircle.area();
890
+ ```
891
+
892
+ ### Implementations
893
+
894
+ An _ implementation_ is an item that implements a [ trait] ( #traits ) for a
895
+ specific type.
896
+
897
+ Implementations are defined with the keyword ` impl ` .
898
+
899
+ ```
900
+ # #[derive(Copy, Clone)]
901
+ # struct Point {x: f64, y: f64};
902
+ # type Surface = i32;
903
+ # struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
904
+ # trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; }
905
+ # fn do_draw_circle(s: Surface, c: Circle) { }
906
+ struct Circle {
907
+ radius: f64,
908
+ center: Point,
909
+ }
910
+
911
+ impl Copy for Circle {}
912
+
913
+ impl Clone for Circle {
914
+ fn clone(&self) -> Circle { *self }
915
+ }
916
+
917
+ impl Shape for Circle {
918
+ fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
919
+ fn bounding_box(&self) -> BoundingBox {
920
+ let r = self.radius;
921
+ BoundingBox {
922
+ x: self.center.x - r,
923
+ y: self.center.y - r,
924
+ width: 2.0 * r,
925
+ height: 2.0 * r,
926
+ }
927
+ }
928
+ }
929
+ ```
930
+
931
+ It is possible to define an implementation without referring to a trait. The
932
+ methods in such an implementation can only be used as direct calls on the values
933
+ of the type that the implementation targets. In such an implementation, the
934
+ trait type and ` for ` after ` impl ` are omitted. Such implementations are limited
935
+ to nominal types (enums, structs, trait objects), and the implementation must
936
+ appear in the same crate as the ` self ` type:
937
+
938
+ ```
939
+ struct Point {x: i32, y: i32}
940
+
941
+ impl Point {
942
+ fn log(&self) {
943
+ println!("Point is at ({}, {})", self.x, self.y);
944
+ }
945
+ }
946
+
947
+ let my_point = Point {x: 10, y:11};
948
+ my_point.log();
949
+ ```
950
+
951
+ When a trait _ is_ specified in an ` impl ` , all methods declared as part of the
952
+ trait must be implemented, with matching types and type parameter counts.
953
+
954
+ An implementation can take type parameters, which can be different from the
955
+ type parameters taken by the trait it implements. Implementation parameters
956
+ are written after the ` impl ` keyword.
957
+
958
+ ```
959
+ # trait Seq<T> { fn dummy(&self, _: T) { } }
960
+ impl<T> Seq<T> for Vec<T> {
961
+ /* ... */
962
+ }
963
+ impl Seq<bool> for u32 {
964
+ /* Treat the integer as a sequence of bits */
965
+ }
966
+ ```
967
+
968
+ ### External blocks
969
+
970
+ External blocks form the basis for Rust's foreign function interface.
971
+ Declarations in an external block describe symbols in external, non-Rust
972
+ libraries.
973
+
974
+ Functions within external blocks are declared in the same way as other Rust
975
+ functions, with the exception that they may not have a body and are instead
976
+ terminated by a semicolon.
977
+
978
+ Functions within external blocks may be called by Rust code, just like
979
+ functions defined in Rust. The Rust compiler automatically translates between
980
+ the Rust ABI and the foreign ABI.
981
+
982
+ Functions within external blocks may be variadic by specifying ` ... ` after one
983
+ or more named arguments in the argument list:
984
+
985
+ ``` ignore
986
+ extern {
987
+ fn foo(x: i32, ...);
988
+ }
989
+ ```
990
+
991
+ A number of [ attributes] ( #ffi-attributes ) control the behavior of external blocks.
992
+
993
+ By default external blocks assume that the library they are calling uses the
994
+ standard C ABI on the specific platform. Other ABIs may be specified using an
995
+ ` abi ` string, as shown here:
996
+
997
+ ``` ignore
998
+ // Interface to the Windows API
999
+ extern "stdcall" { }
1000
+ ```
1001
+
1002
+ There are three ABI strings which are cross-platform, and which all compilers
1003
+ are guaranteed to support:
1004
+
1005
+ * ` extern "Rust" ` -- The default ABI when you write a normal ` fn foo() ` in any
1006
+ Rust code.
1007
+ * ` extern "C" ` -- This is the same as ` extern fn foo() ` ; whatever the default
1008
+ your C compiler supports.
1009
+ * ` extern "system" ` -- Usually the same as ` extern "C" ` , except on Win32, in
1010
+ which case it's ` "stdcall" ` , or what you should use to link to the Windows API
1011
+ itself
1012
+
1013
+ There are also some platform-specific ABI strings:
1014
+
1015
+ * ` extern "cdecl" ` -- The default for x86\_ 32 C code.
1016
+ * ` extern "stdcall" ` -- The default for the Win32 API on x86\_ 32.
1017
+ * ` extern "win64" ` -- The default for C code on x86\_ 64 Windows.
1018
+ * ` extern "sysv64" ` -- The default for C code on non-Windows x86\_ 64.
1019
+ * ` extern "aapcs" ` -- The default for ARM.
1020
+ * ` extern "fastcall" ` -- The ` fastcall ` ABI -- corresponds to MSVC's
1021
+ ` __fastcall ` and GCC and clang's ` __attribute__((fastcall)) `
1022
+ * ` extern "vectorcall" ` -- The ` vectorcall ` ABI -- corresponds to MSVC's
1023
+ ` __vectorcall ` and clang's ` __attribute__((vectorcall)) `
1024
+
1025
+ Finally, there are some rustc-specific ABI strings:
1026
+
1027
+ * ` extern "rust-intrinsic" ` -- The ABI of rustc intrinsics.
1028
+ * ` extern "rust-call" ` -- The ABI of the Fn::call trait functions.
1029
+ * ` extern "platform-intrinsic" ` -- Specific platform intrinsics -- like, for
1030
+ example, ` sqrt ` -- have this ABI. You should never have to deal with it.
1031
+
1032
+ The ` link ` attribute allows the name of the library to be specified. When
1033
+ specified the compiler will attempt to link against the native library of the
1034
+ specified name.
1035
+
1036
+ ``` {.ignore}
1037
+ #[link(name = "crypto")]
1038
+ extern { }
1039
+ ```
1040
+
1041
+ The type of a function declared in an extern block is `extern "abi" fn(A1, ...,
1042
+ An) -> R` , where ` A1...An` are the declared types of its arguments and ` R` is
1043
+ the declared return type.
1044
+
1045
+ It is valid to add the ` link ` attribute on an empty extern block. You can use
1046
+ this to satisfy the linking requirements of extern blocks elsewhere in your code
1047
+ (including upstream crates) instead of adding the attribute to each extern block.
0 commit comments