W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
函數(shù)很好,但是如果你想要在一些數(shù)據(jù)上調用很多函數(shù),那是非常不合適的。請思考以下代碼:
baz(bar(foo)));
我們從左往右讀這些代碼,就會看到 ‘baz bar foo’。但是這并不是我們由內-外調用函數(shù)的順序:‘foo bar baz’。如果我們這樣寫,會不會更好?
foo.bar().baz();
幸運的是,你可能已經猜到了,關于上面問題的答案,可以! Rust 提供了一種可以通過 impl 關鍵字來使用‘方法調用語法’的能力。
以下代碼展示了它是怎樣工作的:
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}
fn main() {
let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
println!("{}", c.area());
}
以上代碼將打印 12.566371。
我們已經建了一個表示一個圓的結構體。然后我們寫一個 impl 塊,同時我們在塊中定義一個方法,area。
方法使用一個特殊的第一參數(shù),其中有三個變量:self,&self 和 &mut self。你可以將這個第一參數(shù)想象成 foo.bar() 中的 foo。這三種變量對應于 foo 可能成為的三種東西:如果它只是堆棧中的一個值使用 self,如果它是一個引用使用 &self,如果它是一個可變引用使用 &mut self。因為我們使用了 &self作為 area 的參數(shù),我們可以像其他參數(shù)一樣使用它。由于我們知道它是一個 Circle,我們可以像訪問其它結構體一樣,訪問 radius。
我們應默認使用 &self,同時相對于取得所有權,你應該更傾向于借用,以及使用不可變的引用來頂替可變的引用。以下是關于所有三個變量的一個例子:
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn reference(&self) {
println!("taking self by reference!");
}
fn mutable_reference(&mut self) {
println!("taking self by mutable reference!");
}
fn takes_ownership(self) {
println!("taking ownership of self!");
}
}
所以,至此我們知道了怎樣去調用一個方法,諸如 foo.bar()。但是我們原來的例子 foo.bar().baz() 的例子怎么辦?這就是所謂的‘方法鏈接’,我們可以通過返回 self 來完成它。
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
fn grow(&self, increment: f64) -> Circle {
Circle { x: self.x, y: self.y, radius: self.radius + increment }
}
}
fn main() {
let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
println!("{}", c.area());
let d = c.grow(2.0).area();
println!("{}", d);
}
檢查返回類型:
fn grow(&self) -> Circle {
我們只是說我們返回了一個 Circle。通過這個方法,我們可以將一個新的圓圈增加到任意大小。
你還可以定義一個不使用 self 作為參數(shù)的關聯(lián)函數(shù)。以下代碼是在 Rust 代碼中非常常見的一種模式:
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn new(x: f64, y: f64, radius: f64) -> Circle {
Circle {
x: x,
y: y,
radius: radius,
}
}
}
fn main() {
let c = Circle::new(0.0, 0.0, 2.0);
} #
這個‘關聯(lián)函數(shù)’為我們生成一個新的 Circle。請注意,關聯(lián)函數(shù)被 Struct::function() 語法調用,而不是 ref.method() 語法。其他一些語言稱關聯(lián)函數(shù)為‘靜態(tài)方法’。
假如我們想要我們的用戶能夠創(chuàng)建 Circles,但是我們只允許他們設置他們關心的屬性。否則,x 和 y 的屬性將會是 0.0,同時 radius 為 1.0。Rust 沒有方法重載,參數(shù)命名或者變量參數(shù)。我們使用生成器模式來代替它。如以下代碼所示:
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}
struct CircleBuilder {
x: f64,
y: f64,
radius: f64,
}
impl CircleBuilder {
fn new() -> CircleBuilder {
CircleBuilder { x: 0.0, y: 0.0, radius: 1.0, }
}
fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
self.x = coordinate;
self
}
fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
self.y = coordinate;
self
}
fn radius(&mut self, radius: f64) -> &mut CircleBuilder {
self.radius = radius;
self
}
fn finalize(&self) -> Circle {
Circle { x: self.x, y: self.y, radius: self.radius }
}
}
fn main() {
let c = CircleBuilder::new()
.x(1.0)
.y(2.0)
.radius(2.0)
.finalize();
println!("area: {}", c.area());
println!("x: {}", c.x);
println!("y: {}", c.y);
}
我們這里所做的就是建立了另一個結構體,CircleBuilder。我們已經對它定義了我們的生成器方法。我們也已經在 Circle 上定義了我們的 area() 方法。我們又在 CircleBuilder 上定義了另一方法:finalize()。這個方法從生成器中創(chuàng)建了我們的最后的 Circle?,F(xiàn)在,我們已經使用類型系統(tǒng)來強化我們關心的事情:我們可以使用在 CircleBuilder 上的方法來限制以我們選擇的任何方式制作 Circle。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: