const ref
パラメータとconst
メンバー関数
この章では、パラメータおよびメンバー関数を、immutable
変数とも一緒に使用できるように、const
としてマークする方法について説明する。const
パラメータについては、前の章で説明したので、この章では、すでに知っている機能について、一部復習する。
この章の例では構造体のみを使用しているが、const
メンバー関数はクラスにも適用される。
immutable
オブジェクト
immutable
変数を変更できないことは既に説明した。
readingTime
変更できない:
コンパイラは、immutable
オブジェクトをいかなる方法でも変更することを許可しない。
ref
const
でないパラメーター
この概念は、関数パラメータの章で既に説明した。ref
とマークされたパラメータは、関数内で自由に変更することができる。そのため、関数が実際にパラメータを変更しない場合でも、コンパイラはimmutable
オブジェクトをそのパラメータとして渡すことを許可しない。
コンパイラは、immutable
warmUpTime
をtotalSeconds
に渡すことを許可しない。これは、その関数がパラメータが変更されないことを保証しないためである。
const ref
パラメーター
const ref
は、関数によってパラメータが変更されないことを意味する。
このような関数は、オブジェクトの不変性がコンパイラによって強制されるため、immutable
オブジェクトをパラメータとして受け取ることができる。
const ref
の代替として、in ref
がある。後の章で説明するように、in
は、パラメータが関数の入力としてのみ使用され、その変更は許可されないことを意味する。
const
以外のメンバー関数
TimeOfDay.increment
メンバー関数で見たように、オブジェクトはメンバー関数によっても変更することができる。increment()
は、呼び出されたオブジェクトのメンバーを変更する。
const
メンバー関数
一部のメンバー関数は、呼び出されたオブジェクトを変更しない。そのような関数の例として、toString()
がある。
toString()
の目的は、オブジェクトを文字列形式で表すことであるため、オブジェクトを変更すべきではない。
メンバー関数がオブジェクトを変更しないことは、パラメータリストの後にconst
キーワードを付けることで宣言される。
const
によって、オブジェクト自体がメンバー関数によって変更されないことが保証される。その結果、toString()
メンバー関数は、immutable
オブジェクトでも呼び出すことができる。そうしないと、構造体のtoString()
が呼び出されない。
出力は期待した05:30
ではなく、TimeOfDay.toString
の代わりにジェネリック関数が呼び出されたことを示している。
immutable(TimeOfDay)(5, 30)
さらに、immutable
オブジェクトに対してtoString()
を明示的に呼び出すと、コンパイルエラーが発生する:
したがって、前の章で定義したtoString()
関数はすべて誤って設計されている。これらはconst
としてマークすべきでした。
注釈: const
キーワードは、関数の定義の前に指定することもできる。
このバージョンでは、const
が戻り値の型の一部であるとの誤解を与える可能性があるため、パラメータリストの後に指定することをお勧めする。
inout
メンバー関数
関数パラメータの章で見たように、inout
はパラメータの変更可能性を戻り値の型に渡す。
同様に、inout
メンバー関数は、オブジェクトの変更可能性を関数の戻り値の型に渡す。
異なる変更可能性を持つ3つのオブジェクトによって返される3つのスライスは、それらを返したオブジェクトと一致している。
immutable(int)[]
const(int)[]
int[]
const
およびimmutable
オブジェクトでも呼び出さなければならないため、inout
メンバー関数は、const
であるかのようにコンパイルされる。
使用方法
- 関数によってパラメータが変更されないことを保証するには、そのパラメータに
in
、const
、またはconst ref
を指定する。 - メンバー関数がオブジェクトを変更しないことは、パラメータリストの後に
const
キーワードで宣言される:これにより、不必要な制限がなくなるため、構造体(またはクラス)の有用性が高まる。この本の残りの部分では、このガイドラインに従った例を示す。