|
|
@ -1,72 +1,72 @@
|
|
|
|
// Struct
|
|
|
|
// Struct
|
|
|
|
struct Point {
|
|
|
|
struct Point {
|
|
|
|
x: i32,
|
|
|
|
x: i32,
|
|
|
|
y: i32,
|
|
|
|
y: i32,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let origin: Point = Point { x: 0, y: 0 };
|
|
|
|
let origin: Point = Point { x: 0, y: 0 };
|
|
|
|
|
|
|
|
|
|
|
|
// A struct with unnamed fields, called a ‘tuple struct’
|
|
|
|
// A struct with unnamed fields, called a ‘tuple struct’
|
|
|
|
struct Point2(i32, i32);
|
|
|
|
struct Point2(i32, i32);
|
|
|
|
let origin2 = Point2(0, 0);
|
|
|
|
let origin2 = Point2(0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Basic C-like enum
|
|
|
|
// Basic C-like enum
|
|
|
|
enum Direction {
|
|
|
|
enum Direction {
|
|
|
|
Left,
|
|
|
|
Left,
|
|
|
|
Right,
|
|
|
|
Right,
|
|
|
|
Up,
|
|
|
|
Up,
|
|
|
|
Down,
|
|
|
|
Down,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let up = Direction::Up;
|
|
|
|
let up = Direction::Up;
|
|
|
|
|
|
|
|
|
|
|
|
// Enum with fields
|
|
|
|
// Enum with fields
|
|
|
|
enum OptionalI32 {
|
|
|
|
enum OptionalI32 {
|
|
|
|
AnI32(i32),
|
|
|
|
AnI32(i32),
|
|
|
|
Nothing,
|
|
|
|
Nothing,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let two: OptionalI32 = OptionalI32::AnI32(2);
|
|
|
|
let two: OptionalI32 = OptionalI32::AnI32(2);
|
|
|
|
let nothing = OptionalI32::Nothing;
|
|
|
|
let nothing = OptionalI32::Nothing;
|
|
|
|
|
|
|
|
|
|
|
|
// Generics //
|
|
|
|
// Generics //
|
|
|
|
struct Foo<T> { bar: T }
|
|
|
|
struct Foo<T> { bar: T }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// This is defined in the standard library as `Option`
|
|
|
|
// This is defined in the standard library as `Option`
|
|
|
|
enum Optional<T> {
|
|
|
|
enum Optional<T> {
|
|
|
|
SomeVal(T),
|
|
|
|
SomeVal(T),
|
|
|
|
NoVal,
|
|
|
|
NoVal,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Methods //
|
|
|
|
// Methods //
|
|
|
|
impl<T> Foo<T> {
|
|
|
|
impl<T> Foo<T> {
|
|
|
|
// Instance methods take an explicit `self` parameter.
|
|
|
|
// Instance methods take an explicit `self` parameter.
|
|
|
|
// Using `self` on its own will consume the caller, while
|
|
|
|
// Using `self` on its own will consume the caller, while
|
|
|
|
// `&self` or `&mut self` will create immutable and mutable
|
|
|
|
// `&self` or `&mut self` will create immutable and mutable
|
|
|
|
// references, respectively.
|
|
|
|
// references, respectively.
|
|
|
|
fn get_bar(self) -> T {
|
|
|
|
fn get_bar(self) -> T {
|
|
|
|
self.bar
|
|
|
|
self.bar
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Static methods don't take a `self` parameter, but can still
|
|
|
|
// Static methods don't take a `self` parameter, but can still
|
|
|
|
// use the generic `T` type.
|
|
|
|
// use the generic `T` type.
|
|
|
|
fn do_baz(msg: &str, baz: T) -> T {
|
|
|
|
fn do_baz(msg: &str, baz: T) -> T {
|
|
|
|
println!("{}", msg);
|
|
|
|
println!("{}", msg);
|
|
|
|
baz
|
|
|
|
baz
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Here `T` is inferred to be some integer type
|
|
|
|
}
|
|
|
|
let a_foo = Foo { bar: 1 };
|
|
|
|
// Here `T` is inferred to be some integer type
|
|
|
|
println!("{}", a_foo.get_bar()); // 1
|
|
|
|
let a_foo = Foo { bar: 1 };
|
|
|
|
|
|
|
|
println!("{}", a_foo.get_bar()); // 1
|
|
|
|
|
|
|
|
|
|
|
|
// `T` can be whatever you want, using "turbofish" syntax
|
|
|
|
// `T` can be whatever you want, using "turbofish" syntax
|
|
|
|
// The statement below prints "Hello" and sets `result` to 24
|
|
|
|
// The statement below prints "Hello" and sets `result` to 24
|
|
|
|
let result: i32 = Foo::<i32>::do_baz("Hello", 24);
|
|
|
|
let result: i32 = Foo::<i32>::do_baz("Hello", 24);
|
|
|
|
|
|
|
|
|
|
|
|
// Traits (known as interfaces or typeclasses in other languages) //
|
|
|
|
// Traits (known as interfaces or typeclasses in other languages) //
|
|
|
|
trait Frobnicate<T> {
|
|
|
|
trait Frobnicate<T> {
|
|
|
|
fn frobnicate(self) -> Option<T>;
|
|
|
|
fn frobnicate(self) -> Option<T>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl<T> Frobnicate<T> for Foo<T> {
|
|
|
|
impl<T> Frobnicate<T> for Foo<T> {
|
|
|
|
fn frobnicate(self) -> Option<T> {
|
|
|
|
fn frobnicate(self) -> Option<T> {
|
|
|
|
Some(self.bar)
|
|
|
|
Some(self.bar)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let another_foo = Foo { bar: 1 };
|
|
|
|
}
|
|
|
|
println!("{:?}", another_foo.frobnicate()); // Some(1)
|
|
|
|
let another_foo = Foo { bar: 1 };
|
|
|
|
|
|
|
|
println!("{:?}", another_foo.frobnicate()); // Some(1)
|
|
|
|