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キーワードで宣言される:これにより、不必要な制限がなくなるため、構造体(またはクラス)の有用性が高まる。この本の残りの部分では、このガイドラインに従った例を示す。