99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

方法語法

2018-08-12 22:03 更新

方法語法

函數(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。通過這個方法,我們可以將一個新的圓圈增加到任意大小。

關聯(lián)函數(shù)

你還可以定義一個不使用 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,但是我們只允許他們設置他們關心的屬性。否則,xy 的屬性將會是 0.0,同時 radius1.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。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號