この記事はQiitaに投稿されたものの転載です。


自分の進捗表示用パッケージprogressにPRが来た。

Bars: bug on narrow terminals when non-ascii fill character is used

どうやら文字列の長さを得るときはlengthではいけない時があるそうだ。

どういうことか

import std.stdio;

void main()
{
    string ascii = "a";
    string non_ascii = "あ";
    writeln(ascii.length);
    writeln(non_ascii.length);
}
1
3

"a""あ"も1文字のはずだが、"あ".length3になってしまっている。

writeln(cast(void[]) ascii);
writeln(cast(void[]) non_ascii);
[97]
[227, 129, 130]

lengthは文字列のバイト数を返しているようだ。

std.range.primitives.walkLength

std.range.primitives.walkLengthは、empty == trueになるまで何回popFront()ができるか実際に試してみて、それで得られた長さを返す。

import std.stdio;
import std.range : walkLength;

void main()
{
    string ascii = "a";
    string non_ascii = "あ";
    writeln(ascii.walkLength);
    writeln(non_ascii.walkLength);
}
1
1

ちゃんと正しい文字数が得られている。