Zenにおける文字列の扱いについて解説します。
まず、Zenには文字列専用の型は存在しません。全てのテキストはUTF-8でエンコードされたバイト列として処理されます。
実行時に動的に文字数が変化する文字列を作るには、標準ライブラリの
ArrayList
またはBuffer
を使います。
文字列は""
で囲う単一行の文字列リテラルと、\\
から始まる複数行の文字列リテラルで記述します。
文字列リテラルはu8
の配列です。""
で囲んだ中身が単一行の文字列リテラルになります。また、その配列はC言語と同様NULL文字 (\0
) で終端しています。
単一行の文字列リテラル内では改行できません。
examples/ch02-primitives/src/strings.zen:4:16
test "string literals" {
const hello = "hello";
ok(@TypeOf(hello) == *[5:0]u8);
ok(hello[0] == 'h');
ok(hello.len == 5);
// ひらがなは1文字3バイト
const japanese = "こんにちは";
ok(@TypeOf(japanese) == *[15:0]u8);
// 「こ」は`{ 0xe3, 0x81, 0x93 }`
ok(japanese[0] == 0xe3);
ok(japanese.len == 15);
}
上の例では、変数 hello
の型は *[5:0]u8
です。配列のポインタ型に似ていますが :0
がついていることで "hello"
がNULL文字で終端していることを示しています。
文字列リテラルはNULL文字で終端していますが、要素数にNULL文字の分は含みません。上の例では変数 hello
の要素数はNULL文字を含まない 5
となります。
終端文字自体にはアクセスすることはできません。
以下のコードはコンパイルエラーになります。
examples/ch02-primitives/src/strings.zen:18:20
test "termination character access" {
const hello = "hello";
ok(hello[5] == 0);
}
error[E04028]: index is out of bounds
ok(hello[5] == 0);
いくつかの文字はバックスラッシュ (\
) によるエスケープが必要です。
文字 | エスケープシーケンス |
---|---|
シングルクォート (' ) | \' |
ダブルクォート (" ) | \" |
改行 | \n |
キャリッジリターン | \r |
タブ | \t |
バックスラッシュ (\ ) | \\ |
16進数文字コード | \xHH |
16進数Unicode | \u{HHHHHH} |
例えば、次のようなエスケープシーケンスにより、文字列リテラル内にUnicodeの文字を埋め込むことができます。
examples/ch02-primitives/src/strings.zen:24:28
test "escape sequence" {
const japanese = "こんにちは";
const unicode = "こ\u{3093}にちは";
equalSlices(u8, japanese, unicode);
}
\\
で複数行の文字列リテラルを記述できます。
改行は文字列リテラルに\n
で格納されます。ただし、最終行の改行は含まれません。
test "string multi-line literals" {
const hello =
\\Hello
\\World
;
equalSlices(u8, hello, "Hello\nWorld");
}
複数行の文字列リテラルでは、エスケープシーケンスを記述することはできません。
test "no-escape sequence" {
const text_not_newline =
\\\n
;
ok(text_not_newline[0] != '\n');
const text_not_n =
\\\u{3093}
;
ok(text_not_n.len > 3);
for("\u{3093}") | chara, idx | {
ok(text_not_n[idx] != chara);
}
}
配列リテラルと同様に、コンパイル時計算可能な文字列リテラルは、++
演算子によって連結することができます。
examples/ch02-primitives/src/strings.zen:30:35
test "concatenates string literals" {
const hello = "hello";
const world = "world";
const message = hello ++ " " ++ world ++ "\n";
equalSlices(u8, message, "hello world\n");
}
また、コンパイル時計算可能な文字列リテラルは、**
演算子によって複数回繰り返した文字列を作ることができます。
examples/ch02-primitives/src/strings.zen:37:41
test "multiplies string literals" {
const hyphen = "-";
const line = hyphen ** 10;
equalSlices(u8, line, "----------");
}
文字列はu8
の配列なので、スライスとして使用することもできます。
examples/ch02-primitives/src/strings.zen:43:48
test "string slice" {
const hello = "hello world";
const world = hello[6..];
equalSlices(u8, world, "world");
}
☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2020 connectFree Corporation. All rights reserved. | 特定商取引法に基づく表示
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.