球魚
你己經被幸運螃蟹造訪了
Object-oriented programs are made up of objects.
An object packages both data and the procedures that operate on that data.
The procedures are typically called methods or operations.
struct Circle {
radius: f64;
}
enum Number {
Int(i32),
Float(f32).
}
trait Shape {
fn area(self: &Self) -> f64;
}
impl Shape for Circle {
fn area(&self) -> f64 {
self.radius * self.radius * 3.14
}
}
trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
impl Summary for NewsArticle {}
let article = NewsArticle {
headline: String::from("Wow!"),
content: String::from("The is an apple."),
};
println!("New article available! {}", article.summarize());
// -> New article available! (Read more...)
trait Shape {
fn area(self: &Self) -> f64;
}
fn test (arg: Shape) {} // => X
fn test() =-> Shape {} // => X
trait Shape {
fn area(self: &Self) -> f64;
}
假設今天要製作 GUI 相關的 library,預期會有像 Button、Image、Text 之類的 component,所有的 component 都有 function draw
首先寫出 Draw trait
trait Draw {
fn draw(&self);
}
再來,有一個 Screen 的 struct 紀錄要被打印的 component
struct Screen<T: Draw> {
components: Vec<T>,
}
Screen 打印 component 的 function
impl<T> Screen<T>
where T: Draw {
fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}
首先寫出 Draw trait
trait Draw {
fn draw(&self);
}
再來,有一個 Screen 的 struct 紀錄要被打印的 component
struct Screen {
components: Vec<Box<dyn Draw>>,
}
// Box<dyn Draw> 就是 trait object
Screen 打印 component 的 function
impl Screen {
fn run(&self) {
for component in self.components.iter() {
component.draw(); // 有自動 deref
}
}
}
有些 trait 不是 object safe,不是 object safe 的 trait 就無法使用 trait object
以下列舉幾種可能會在編譯期間報錯的情況
第一個例子 Sized 作用在 Foo trait 本身上,當建構 trait object 時,Sized 需要在編譯期間確定空間大小, 因無法確定 Foo trait 的大小而編譯失敗
trait Foo where Self: Sized {
fn foo(&self);
}
impl Foo for i32 {
fn foo(&self) { println!("{}", self); }
}
fn main () {
let x = 1_i32;
x.foo();
let p = &x as &dyn Foo; // 這邊會編譯失敗
p.foo();
}
trait Foo {
fn foo(&self) where Self: Sized;
}
impl Foo for i32 {
fn foo(&self) { println!("{}", self); }
}
fn main () {
let x = 1_i32;
x.foo();
let p = &x as &dyn Foo;
p.foo(); // 這邊會編譯失敗
}
fn main() {
let s = String::new();
let p: &dyn Clone = &s as &dyn Clone(); // 這邊會報錯
}
// 同理剛剛的 Screen 例子
struct Screen {
pub components: Vec<Box<dyn Clone>>, // 這邊會報錯
}
trait Foo {
fn new() -> Self where Self: Sized;
fn foo(&self);
}
// Foo is object safe
trait Foo {
fn foo<T>(&self, value: T);
}
fn fail(x: &dyn Foo) {
x.foo("bar"); // T = &str
x.foo(1_u8); // T = u8
// 編譯器表示:黑人問號??
}
我原本是想要開個黑客松之類的活動
所以有跟一個 Rust 大大,要了他開的課程的免費邀請碼兩組
原本是要當獎品的,要都要了,我還是想把他當獎品
課程是這個:https://www.packtpub.com/application-development/building-reusable-code-rust-video