Cairoには文字列のネイティブ型はありませんが、文字列を扱う方法が2つあります。シングルクォートを使うショート文字列と、ダブルクォートを使うByteArrayです。
ショート文字列は、各文字が1バイトでエンコードされるASCII文字列です。
Cairoがショート文字列にデフォルトで使う型はfelt252で、その最大長はわずか31文字です。
// below are different ways to write the same value
let name: felt252 = 'Jane'; // short string format
let name: felt252 = 0x4a616e65; // byte format
let name: felt252 = 1247899237; // decimal format
技術的には、felt252より小さい整数型はすべてショート文字列形式で表現できます。
// all of the below are equal u8 values, they are just written using different formats!
let lowercase_a_in_ascii: u8 = 'a'; // short string format
let lowercase_a_in_ascii: u8 = 0x61; // byte format
let lowercase_a_in_ascii: u8 = 97; // decimal format
31文字より長い文字列には、CairoはByteArrayを用意しています。長さは無制限です。
let long_string: ByteArray = "this is a string which has more than 31 characters";
ByteArrayは+演算子で連結できます。
"Jane" + " " + "Austen"
// => "Jane Austen"
一部の特殊文字は、先頭にバックスラッシュを付けてエスケープする必要があります。たとえば、文字列内でタブは\t、改行は\nです。
"How is the weather today?\nIt's sunny"
// =>
// How is the weather today?
// It's sunny
ByteArray内の個々のバイトには、インデックスを使ってアクセスすることもできます。
ただし注意してください。返されるバイトの型はu8であり、ByteArrayではありません!
let hello: ByteArray = "Hello World!";
let exclamation_mark: u8 = hello[11];
// => 33
コアライブラリには、ByteArrayを操作するための便利なメソッドや演算子がたくさん用意されています。
ByteArrayのメソッドについて詳しくは、ByteArrayTraitドキュメントを参照してください。
いくつか例を見てみましょう。
let name: felt252 = 'Jane';
let mut greeting: ByteArray = "Welcome ";
// append_word appends a single word of a given number of bytes to the end of the ByteArray
greeting.append_word(name, 4);
// => "Welcome Jane"
// rev returns a ByteArray with the all characters reversed
let rev_greeting = greeting.rev();
// => "enaJ emocleW"
近くに「Tech Palace」という家電量販店があります。 店のオーナーは最近、マーケティングメッセージの表示や、お客さんが入口でポイントカードをスキャンしたときに特別な挨拶を表示するために、大きなディスプレイを設置しました。 このディスプレイはたくさんの小さなLEDライトでできていて、複数行のテキストを表示できます。
店のオーナーは、新しいディスプレイのテキストを生成するコードについて、助けを求めています。
ポイントカードをスキャンするほとんどのお客さんに対して、店のオーナーは、ディスプレイにWelcome to the Tech Palace, と、それに続けてお客さんの名前を大文字で表示したいと考えています。
お客さんの名前を短い文字列(felt252)の引数として受け取り、目的のメッセージをByteArrayとして返す関数welcome_messageを実装してください。
welcome_message("Judy")
// => Welcome to the Tech Palace, JUDY
店でたくさん買い物をする常連のお客さんのために、オーナーは、ウェルカムメッセージの前後に星の行を追加して、ウェルカム表示をより華やかにしたいと考えています。 星の行にいくつの星を入れるかはまだ決めていないため、その数を設定できるようにしたいと考えています。
ウェルカムメッセージ(ByteArray)と、1行あたりの星の数(型u32)を引数として受け取る関数add_borderを書いてください。
この関数は3行からなるByteArrayを返します。1行目は指定した数の星、2行目は渡されたままのウェルカムメッセージ、3行目はもう1行の星です。
add_border("Welcome!", 10)
次のようになります。
**********
Welcome!
**********
この新しいディスプレイを設置する前は、店には似たようなディスプレイがあり、変更できない固定の行しか表示できませんでした。 オーナーは、古いマーケティングメッセージの一部を新しいディスプレイで再利用したいと考えています。 しかし、そのデータにはすでに星の枠と、いくつかの厄介な空白文字が含まれています。 ここでの課題は、メッセージを再利用できるようにきれいにすることです。
古いマーケティングメッセージをByteArrayとして受け取る関数clean_up_messageを実装してください。
この関数はまず、テキストからすべての星を取り除き、その後、残ったテキストの先頭と末尾の空白文字を取り除きます。
そして、きれいにしたメッセージを返します。
let message: ByteArray = "
**************************
* BUY NOW, SAVE 10% *
**************************
";
clean_up_message(message)
// => BUY NOW, SAVE 10%