Flat Leon Works

アプリやゲームを作ってます。

【Nim】文字列リテラルと書式について

この記事は「Nim Advent Calendar 2021」の21日目の記事として登録させてもらっています。

文字列リテラルと書式の組み合わせ爆発

Nimは複数の文字列リテラルの書き方があり、さらに書式も複数の書き方があります。

書式の書き方を羅列してみると…

  • &"書式"
  • &r"書式"
  • &"""書式"""
  • fmt"書式"
  • fmt( "書式" )
  • "書式".fmt
  • fmt"""書式"""
  • fmt( """書式""" )
  • """書式""".fmt
  • fmt( r"書式" )
  • r"書式".fmt

あああー、組み合わせが爆発しています。これらの組み合わせの違いにより微妙に挙動が異なるので、かなり混乱しそうです。

しかし、これらは基本的なルールを理解することで挙動の違いを知ることができます。

文字列リテラルと書式のルール

文字列リテラルの種類

文字列リテラルは3種類あります。それぞれ、「エスケープの可否」「改行の可否」「"の打ち方」に違いがあります。

名称 記述方法 エスケープ 改行 "の打ち方
文字列リテラル(String literals) "文字列" される できない \"
三重クオート文字列リテラル(Triple quoted string literals) """文字列""" されない できる "
raw文字列リテラル(Raw string literals) r"文字列" されない できない ""

一般化raw文字列リテラル

identity文字列リテラルと記述するとidentity( 文字列リテラル )に変換されます。これを一般化raw文字列リテラル(Generalized raw string literals)と呼びます*1。変換時に文字列リテラルの種類が変わる場合があります。

変換前の文字列リテラル 変換後の文字列リテラル
“文字列” r”文字列”
“””文字列””” “””文字列”””
r”文字列” ※一般化raw文字列にできない

書式化

書式による文字列生成には&fmtの2種類が使えます。

備考
&文字列リテラル
fmt( 文字列リテラル ) ただのtemplateなので一般化raw文字列が利用可能

ルールのまとめ

  • 文字列リテラルは3種類あり、それぞれ微妙に挙動が違う
  • 一般化文字列リテラルで、文字列リテラルが変換され関数の引数として渡される
  • 書式化には&fmtがあり、fmtは一般化文字列リテラルが使える

冒頭の文字列リテラルを解読する

  • &"書式" : 普通の文字列リテラルで書式化
  • &r"書式" : raw文字列リテラルで書式化
  • &"""書式""" : 三重クオート文字列リテラルで書式化
  • fmt"書式" : raw文字列リテラルで書式化
  • fmt( "書式" ) : 普通の文字列リテラルで書式化
  • "書式".fmt : 普通の文字列リテラルで書式化
  • fmt"""書式""" : 三重クオート文字列リテラルで書式化
  • fmt( """書式""" ) : 三重クオート文字列リテラルで書式化
  • """書式""".fmt : 三重クオート文字列リテラルで書式化
  • fmt( r"書式" ) : raw文字列リテラルで書式化
  • r"書式".fmt : raw文字列リテラルで書式化

こうしてみると注意すべきはfmt"書式"の書き方、つまり一般化raw文字列リテラルだけですね *2。この書き方だけは"書式"r"書式"に変換されます。 あとは、それぞれの挙動の違いはどの文字列リテラルの種類なのかで判断すればよいだけです。

*1:日本語訳としては私が勝手に付けたものです

*2:そもそも一般化raw文字列リテラルって便利ですかね?fmt"書式"ではなく"書式".fmtなら、見た目通り"書式"は"書式"のままなので余計な混乱をせずに済みますし、記述の手間も対して変わらないと思います