2024/05/02

関数の引数と値渡し

チーム開発』のラベルを付けた前回の記事『関数のインターフェースと独立性』では、関数作成において、引数と戻り値以外のインターフェースをなくせば、独立性が高くなり、後任者に伝わりやすいプログラムになることを紹介しました。

今回は、この引数にもう少し掘り下げたいと思います。


引数のタイプ

VBA の言語仕様として、関数の引数には、値渡しと参照渡しの 2 つのタイプがあります。


◇ 値渡し

値渡しの特徴と使い方は次の通りです。

  • 引数の値はコピーされ関数に渡される
  • 関数内で値を変更しても呼び出し元の値は変更されない
  • 値渡しは、引数の定義で ByVal を指定すること

図式化すると次のようになります。

まず、外側のプログラムで、関数 Sample を呼び出します。引数 a には "Lotus" と入っていて、関数内の変数 b で値を受け取ります。関数 Sample 内で、b の値を "Script" に変化させていますが、関数を抜けた後の変数 a の値に変化はありません。


◇ 参照渡し

参照渡しには次のような特徴があります。

  • 値を保持しているメモリ領域のアドレスを関数に渡す
  • 同じメモリ領域を共有するので、関数内で値を更新すると呼び出し元の値も変更される

先の事例を参照渡しに変更した場合を同じく図式化すると次の通りとなります。

参照渡しの場合は、関数内で値を変更すると呼び出し元の変数 a の値が更新されます。

値渡しの場合、引数の宣言で ByVal と記載しました。LotusScript では、参照渡しを指定するキーワードがありません。ByVal をつけないと参照渡しとなります。


引数の使い方

引数のタイプを指定するには条件があります。

値渡しが設定できるのは、数値や文字列などの単一のデータを表す変数(スカラー型)となります。引数の宣言で ByVal と記述すると値渡し、省略すると参照渡しとなります。

配列や Variant、オブジェクト変数は値渡しは指定できません。必ず参照渡しとなります。


引数のタイプと関数の独立性

引数と戻り値以外のインターフェースを持たない関数を前提に考えます。

引数が値渡しの場合、関数内でどのような処理が行われたとしても、呼び出し元に影響を与えるのは戻り値だけとなります。逆に引数が参照渡しの場合、関数内の処理によっては値が書き換わる可能性があるということです。

独立性という側面で考えた場合、値渡しでよい引数は ByVal と記述することで独立性を高められるということになります。


チーム開発と引数

以前、紹介した『命名規則の例(LotusScript)』で変数の命名規則について記述しました。変数名の先頭がスコープやコーディング上の用途を指定していました。この ”用途” にあたる部分が今回の引数のタイプに該当します(命名規則をまとめたページはこちら)。

下図の通り紹介したのですが、赤枠の部分が引数に関する部分です。

例えば、次のように記述します。

   Sub Sample( ByVal vsName As String )

   Sub Sample( rsName As String )

これで変数名を見るだけで、値渡しか参照渡しかの判定が可能となります。


同様の命名規則は、スカラー変数以外にも適用しています。実際には、値渡しは設定できないのですが、変数名で次のように使い分けています。

vndSample 関数の外側から与えられる文書
関数内で文書を変更しない
rndSample  関数内で文書をセットし呼び出し元へ返す変数

vndSample では、文書は変更しないとなっていますが、別の文書に差し替えない限り、フィールドのセットなどの更新までは禁止していません(利便性優先)。


まとめ

今回は関数の引数にフォーカスして、引数の値渡しと参照渡しについて紹介しました。

かなり細かな話になりましたが、こういった機能があることを理解し、活用することで、より見やすい、理解しやすいプログラムを作成できるようになります。参考になれば幸いです。

0 件のコメント:

コメントを投稿