「D言語/関数」の版間の差分

削除された内容 追加された内容
Angol Mois (トーク | 投稿記録)
Ef3 (トーク | 投稿記録)
→‎スコープ: シャドウイングは許されない(コンパイルエラー)
タグ: 2017年版ソースエディター
64 行
9 -->
 
== スコープブロック文 ==
D言語では、関数の内部における変数の有効範囲(スコープ)の性質が、C言語とはやや違い異なります。なみかっこ
ブロック文( <code>{ ... }</code> で囲まれた部分スコープブロック文と呼ばれ、スコープブロックは変数や関数などのユーザー定義のシンボルが見える範囲の区切りを表します。また、
スコープブロックは入れ子にすること可能です。
 
;[https://paiza.io/projects/Y-ukLeqDBuGKSchaJKdR7Q?language=d コード例]:<syntaxhighlight lang="D" line>
;コード例
<syntaxhighlight lang="D">
import std.stdio;
 
int a = 99;
 
void kansufunc0() {
int a = 2;
writef("aはkansufunc0でいま%d\n", a);
// 新たなスコープ
{
// int a = 42; ← 6行目の a を隠してしまう(シャドウイング)ので a を識別子に使えない。
int a = 42;
writef("aはkansufunc0内の内側のスコープでいま%d\n", a);
}
writef("aはkansufunc0内の内側のスコープでいま%d\n", a);
}
 
void main() {
kansufunc0();
{
kansu();
writef("aはmainでいま%d\n", a);
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
 
aはkansufunc0でいま2
;実行結果
aはfunc0内の内側のスコープでいま2
<pre>
aはkansufunc0内の内側のスコープでいま2
aはkansuでいま42
aはkansuでいま2
aはmainでいま99
</syntaxhighlight lang="D">
</pre>
 
;shadowing
このモジュール自体も一つのスコープであるとみなすことができます。関数を定義する際は、新たなスコープを導入する必要があります。スコープ内で変数を宣言するとき、外側に同じ名前のものがあれば、内部で宣言されたものが優先されます。これを"shadowing"といいます。shadowingした変数はそのスコープでは外側の変数を覆い隠し、外側の変数には何ら影響を及ぼしません。そのため、上のような実行結果になるのです。スコープを抜ければその変数は「消滅」します。
 
;外側のスコープの変数を使用する
スコープの内部で変数をshadowingするまでは、スコープの外側の変数を参照します。(C言語とは、ここらへんの仕組みが違います。)
 
;コード例
111 ⟶ 104行目:
int a = 99;
 
void kansufunc0() {
a = 2; // 変数宣言しない(できない)
 
writef("aはkansufunc0でいま%d\n", a);
}
 
void main() {
kansufunc0();
{
kansu();
writef("aはmainでいま%d\n", a);
}
126 ⟶ 118行目:
;実行結果
<pre>
aはkansufunc0でいま2
aはmainでいま2
</pre>
 
上記の例では、関数 kansufunc0 では新規宣言されておらず、外部の変数を上書きします。
 
その結果、aの値がmainでも「2」に変わります。
 
C言語風に説明するなら「ローカル変数として使いたいなら、ユーザ定義関数内で再度その変数を宣言する必要がある」という事になります。
 
 
== 内部関数 ==