Skip to content

4.15. Method Syntax #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 1, 2016
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 55 additions & 34 deletions 1.6/ja/book/method-syntax.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
% Method Syntax
% メソッドシンタックス
<!-- % Method Syntax -->

Functions are great, but if you want to call a bunch of them on some data, it
can be awkward. Consider this code:
<!-- Functions are great, but if you want to call a bunch of them on some data, it
can be awkward. Consider this code: -->
関数は素晴らしいのですが、幾つかのデータに対し複数の関数をまとめて呼び出したい時、困ったことになります。以下のコードについて考えてみます。

```rust,ignore
baz(bar(foo));
```

We would read this left-to-right, and so we see ‘baz bar foo’. But this isn’t the
<!-- We would read this left-to-right, and so we see ‘baz bar foo’. But this isn’t the
order that the functions would get called in, that’s inside-out: ‘foo bar baz’.
Wouldn’t it be nice if we could do this instead?
Wouldn’t it be nice if we could do this instead? -->
私たちはこれを左から右へ、「baz bar foo」と読むことになりますが、関数が呼び出される順番は異なり、内側から外へ「foo bar baz」となります。もし代わりにこうできたらいいとは思いませんか?

```rust,ignore
foo.bar().baz();
```

Luckily, as you may have guessed with the leading question, you can! Rust provides
the ability to use this ‘method call syntax’ via the `impl` keyword.
<!-- Luckily, as you may have guessed with the leading question, you can! Rust provides
the ability to use this ‘method call syntax’ via the `impl` keyword. -->
最初の質問でもう分かっているかもしれませんが、幸いにもこれは可能です!Rustは `impl` キーワードによってこの「メソッド呼び出し構文」の機能を提供しています。

# Method calls
<!-- # Method calls -->
# メソッド呼び出し

Here’s how it works:
<!-- Here’s how it works: -->
どんな風に動作するかが以下になります。

```rust
struct Circle {
Expand All @@ -41,23 +47,27 @@ fn main() {
}
```

This will print `12.566371`.
<!-- This will print `12.566371`. -->
これは `12.566371` と出力します。

We’ve made a `struct` that represents a circle. We then write an `impl` block,
and inside it, define a method, `area`.
<!-- We’ve made a `struct` that represents a circle. We then write an `impl` block,
and inside it, define a method, `area`. -->
私たちは円を表す `struct` を作りました。その際 `impl` ブロックを書き、その中に `area` というメソッドを定義しています。

Methods take a special first parameter, of which there are three variants:
<!-- Methods take a special first parameter, of which there are three variants:
`self`, `&self`, and `&mut self`. You can think of this first parameter as
being the `foo` in `foo.bar()`. The three variants correspond to the three
kinds of things `foo` could be: `self` if it’s just a value on the stack,
`&self` if it’s a reference, and `&mut self` if it’s a mutable reference.
Because we took the `&self` parameter to `area`, we can use it just like any
other parameter. Because we know it’s a `Circle`, we can access the `radius`
just like we would with any other `struct`.
just like we would with any other `struct`. -->
メソッドに渡す特別な第1引数として、 `self` 、 `&self` 、 `&mut self` という3つの変形があります。 `foo.bar()` の第1引数は `foo` であると考えて下さい。3つの変形は `foo` が成り得る3種類の状態に対応しており、それぞれ `self` がスタック上の値である場合、 `&self` が参照である場合、 `&mut self` がミュータブルな参照である場合となっています。 `area` で `&self` を受け取っているため、他の引数と同じように扱えます。引数が `Circle` であるのは分かっていますから、他の `struct` でするように `radius` へアクセスできます。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foo.bar()の第1引数はfoo` であると考えて下さい

原文の"You can think of this first parameter as being the foo in foo.bar()."とはやや異なっているように感じます。
「第一引数はfoo.bar()に於けるfooと思って下さい」はどうでしょうか。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nits]

area

area では」の方がやや読みやすいかと。


We should default to using `&self`, as you should prefer borrowing over taking
<!-- We should default to using `&self`, as you should prefer borrowing over taking
ownership, as well as taking immutable references over mutable ones. Here’s an
example of all three variants:
example of all three variants: -->
所有権を渡すよりも借用を好んで使うべきなのは勿論のこと、ミュータブルな参照よりもイミュータブルな参照を渡すべきですから、 `&self` を常用すべきです。以下が3種類全ての例です。

```rust
struct Circle {
Expand All @@ -81,8 +91,9 @@ impl Circle {
}
```

You can use as many `impl` blocks as you’d like. The previous example could
have also been written like this:
<!--You can use as many `impl` blocks as you’d like. The previous example could
have also been written like this: -->
好きな数だけ `impl` ブロックを使用することができます。前述の例は以下のように書くこともできるでしょう。

```rust
struct Circle {
Expand Down Expand Up @@ -110,11 +121,13 @@ impl Circle {
}
```

# Chaining method calls
<!-- # Chaining method calls -->
# メソッド呼び出しの連鎖
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ask]
それっぽい訳語ありませんでしたっけ?メソッドチェーンは違いますかね?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ではメソッドチェーンに統一します。


So, now we know how to call a method, such as `foo.bar()`. But what about our
<!-- So, now we know how to call a method, such as `foo.bar()`. But what about our
original example, `foo.bar().baz()`? This is called ‘method chaining’. Let’s
look at an example:
look at an example: -->
ここまでで、`foo.bar()` というようなメソッドの呼び出し方が分かりましたね。ですが元の例の `foo.bar().baz()` はどうなっているのでしょう?これは「メソッドチェーン」と呼ばれています。以下の例を見て下さい。

```rust
struct Circle {
Expand Down Expand Up @@ -142,7 +155,8 @@ fn main() {
}
```

Check the return type:
<!-- Check the return type: -->
以下の返す型を確認して下さい。

```rust
# struct Circle;
Expand All @@ -151,13 +165,16 @@ fn grow(&self, increment: f64) -> Circle {
# Circle } }
```

We just say we’re returning a `Circle`. With this method, we can grow a new
`Circle` to any arbitrary size.
<!-- We just say we’re returning a `Circle`. With this method, we can grow a new
`Circle` to any arbitrary size. -->
単に `Circle` を返しているだけです。このメソッドにより、私たちは新しい `Circle` を任意のサイズに成長させることができます。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nits]

任意のサイズに成長させることができます

メモリ上のサイズではなく円としての半径の大きさのことなのでサイズではなく大きさの方が適切な気がします。
「任意の大きさに拡大することが出来ます」
はどうでしょう。「円を成長させる」というのが日本語としては少し伝わりづらい気がしました。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

良い訳が浮かばず直訳してました、ありがとうございます


# Associated functions
<!-- # Associated functions -->
# 関連関数

You can also define associated functions that do not take a `self` parameter.
Here’s a pattern that’s very common in Rust code:
<!-- You can also define associated functions that do not take a `self` parameter.
Here’s a pattern that’s very common in Rust code: -->
あなたは `self` を引数に取らない関連関数を定義することもできます。以下のパターンはRustのコードにおいて非常にありふれた物です。

```rust
struct Circle {
Expand All @@ -181,18 +198,21 @@ fn main() {
}
```

This ‘associated function’ builds a new `Circle` for us. Note that associated
<!-- This ‘associated function’ builds a new `Circle` for us. Note that associated
functions are called with the `Struct::function()` syntax, rather than the
`ref.method()` syntax. Some other languages call associated functions ‘static
methods’.
methods’. -->
この「関連関数」(associated function)は新たに `Circle` を構築します。この関数は `ref.method()` ではなく、 `Struct::function()` という構文で呼び出されることに注意して下さい。幾つかの言語では、関連関数を「静的メソッド」(static methods)と呼んでいます。

# Builder Pattern
<!-- # Builder Pattern -->
# Builderパターン

Let’s say that we want our users to be able to create `Circle`s, but we will
<!-- Let’s say that we want our users to be able to create `Circle`s, but we will
allow them to only set the properties they care about. Otherwise, the `x`
and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesn’t
have method overloading, named arguments, or variable arguments. We employ
the builder pattern instead. It looks like this:
the builder pattern instead. It looks like this: -->
ユーザが `Circle` を作成できるようにしたいものの、彼らに許可できるのはプロパティを設定することだけだと仮定しましょう。もし指定が無ければ `x` と `y` が `0.0` 、 `radius` が `1.0` であるものとします。Rustはメソッドのオーバーロードや名前付き引数、可変個引数といった機能がない代わりにBuilderパターンを採用しており、それは以下のようになります。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ユーザが Circle を作成できるようにしたいものの、彼らに許可できるのはプロパティを設定することだけだと仮定しましょう。

"allow"、"care about" のニュアンスが抜けているように感じます。
「ユーザが Circle を作成できるようにしたいのですが、興味のあるプロパティだけを設定すれば良いようにしたいとしましょう。」
はどうでしょうか。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KeenS
文章をもう少し自然目に意訳して、
「ユーザが Circle を作成できるようにしつつも、書き換えたいプロパティだけを設定すれば良いようにしたいとしましょう。」
だとどうでしょうか?書き換えたいが過ぎるのであれば「関心のある」ですかね?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

いえ、むしろ「書き換えたい」が一番言い当ててると思います。それでお願いします。


```rust
struct Circle {
Expand Down Expand Up @@ -251,9 +271,10 @@ fn main() {
}
```

What we’ve done here is make another `struct`, `CircleBuilder`. We’ve defined our
<!-- What we’ve done here is make another `struct`, `CircleBuilder`. We’ve defined our
builder methods on it. We’ve also defined our `area()` method on `Circle`. We
also made one more method on `CircleBuilder`: `finalize()`. This method creates
our final `Circle` from the builder. Now, we’ve used the type system to enforce
our concerns: we can use the methods on `CircleBuilder` to constrain making
`Circle`s in any way we choose.
`Circle`s in any way we choose. -->
ここではもう1つの `struct` である `CircleBuilder` を作成しています。その中にBuilderメソッドを定義しました。また `Circle` に `area()` メソッドを定義しました。 そして `CircleBuilder` にもう1つ `finalize()` というメソッドを作りました。このメソッドはBuilderから最終的な `Circle` を作成します。今回、最初の仮定をユーザに強制するため型システムを利用しました。用意した方法から `Circle` を作るという制約を実現するために、この `CircleBuilder` のメソッドを使うことができます。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回、最初の仮定をユーザに強制するため型システムを利用しました。用意した方法から Circle を作るという制約を実現するために、この CircleBuilder のメソッドを使うことができます。

原文の"Now, we’ve used the type system to enforce our concerns: we can use the methods on CircleBuilder to constrain making Circles in any way we choose."は先程の「興味のある値を設定すればいい(=生成するCircleに興味のある部分にだけ制約を与える)」という願望を叶えるために型システムを使って、CircleBuilderのメソッドを使えば自由に制約を与えれるし、制約を与えなかったらデフォルト値が採用されるようにも出来るようにした。CircleBuilderのメソッドは型が合う限りどのように使っても正しくCircleの値を生成出来るという意味かと思います。なので意訳気味ですが
「さて、先程の要求を実施するために型システムを使いました。CircleBuilderのメソッドを好きなように組み合わせて、作るCircleへの制約を与えることが出来ます」
はどうでしょうか。