長さ0の配列、nullの配列

1つ前のエントリについて、長さ0で非nullな配列って、できないの?と思って、以下のコードを組んでみた。

import tango.io.Stdout;

void main()
{
	void out_status(char[] name, char[] a){
		Stdout.formatln("{} .length -> {}", name, a.length);
		Stdout.formatln("{} is null -> {}", name, a is null);
	}

	char[] s = ['a','b'];
	char[] p;

	out_status("s",s);
	out_status("p",p);
	
	Stdout("==").newline;

	char[] q = s[0..0];
	char[0] u = [];
	char[] z = [];

	out_status("q",q);
	out_status("u",u);
	out_status("z",z);
}

出力の結果は以下のとおり。使用したコンパイラdmd(ver1.041)である。

s .length -> 2
s is null -> false
p .length -> 0
p is null -> true
==
q .length -> 0
q is null -> false
u .length -> 0
u is null -> false
z .length -> 0
z is null -> true

出力結果から、以下のことが判る。

  • 配列s(可変長で、2つの要素で初期化)は、長さ2、非nullである。
  • 配列p(可変長で、初期化していない)は、長さ0、nullである。
  • 配列q(可変長で、配列sを長さ0でスライス)は、長さ0、非nullである。
  • 配列u(固定長で、長さ0)は、長さ0、非nullである。
  • 配列z(可変長、長さ0で初期化)は、長さ0、nullである。

sとpとuは、予測したとおりの結果であるが、問題はzである。長さ0の非null配列を生成するかのように見える記述で、nullな配列が生成されることが確認できる。これはちょっと美味しくない。

長さ0・非nullな配列を、「長さ0・nullな配列とは違う意味で」処理しよう/させようと思うのは危険かもしれない。