Skip to content
Go言語とは、Googleが開発した新しいプログラミング言語です。
当サイトではこの新しい言語についての情報を集約していきます。
このサイトの更新が滞っており、情報が古くなっておりますのでご注意ください。

Archive

Archive for 12月, 2009

The Go Programming Language Specificationの翻訳、5回目です。
前回までの訳はGo言語仕様[日本語訳]にまとめてあります。


型は、その型を持つ値に対し具体的な値と操作の組み合わせを規定します。型を表すには型の(パッケージ名を伴なう場合もある)名称(§限定付き識別子、 §型の宣言) または型リテラルで記述します。事前に定義した型から別の新しい型を作成することもできます。

Type      = TypeName | TypeLit | "(" Type ")" .
TypeName  = QualifiedIdent.
TypeLit   = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
	    SliceType | MapType | ChannelType .

論理値型、数値型、文字列型として事前宣言済みの型が用意されています。 コンポジット型(配列、構造体、ポインタ、関数、インタフェース、スライス、マップ、チャネル型)は型リテラルを使って作られます。

型は、その型と関連付けられたメソッド群を持ちます (§インタフェース型、§メソッドの宣言) 。インタフェース型のメソッド群はインタフェース自身です。インタフェース以外の型を仮にTとすると、そのT型のメソッド群はT型のレシーバを持ったすべてのメソッドです。 ポインタ型*Tと対応するメソッド群は、*TまたはT型のレシーバを持ったすべてのメソッドです。(すなわち、T型が持つメソッド群が含まれます。)また各メソッドは、メソッド群内におけるユニークな名前を持っています。

変数の静的な型(または適正な型)は、変数の宣言時に指定された型です。インタフェース型の変数は、他の型とは違って動的な型を持っており、実行時にその変数に格納された値の型が実際の型となります。この動的な型はプログラム実行中に値が入れ替わったとしても、常にインタフェース変数の静的な型と互換のある値が代入されます。非インタフェース型において、動的な型と静的な型は常に一致します。

論理値型

論理値型は、事前宣言済み定数trueまたはfalseによる論理値を表現します。論理値型として事前宣言済みの型はboolです。

数値型

数値型は、整数または浮動小数点の値を表現します。アーキテクチャに依存しない数値型として事前宣言済みの型は、

uint8    符号なし  8-ビット 整数 (0 to 255)
uint16   符号なし 16-ビット 整数 (0 to 65535)
uint32   符号なし 32-ビット 整数 (0 to 4294967295)
uint64   符号なし 64-ビット 整数 (0 to 18446744073709551615)

int8     符号あり  8-ビット 整数 (-128 to 127)
int16    符号あり 16-ビット 整数 (-32768 to 32767)
int32    符号あり 32-ビット 整数 (-2147483648 to 2147483647)
int64    符号あり 64-ビット 整数 (-9223372036854775808 to 9223372036854775807)

float32  IEEE-754 32-ビット 浮動小数値
float64  IEEE-754 64-ビット 浮動小数値

byte     uint8の別名

整数型は一般的なバイナリ形式であり、「n-ビット 整数」型の値はnビットのサイズを持ち、負の値は絶対値を2の補数で表現します。

実装に依存したサイズを持つ数値型も用意されています。

uint     32 または 64 ビット
int      32 または 64 ビット
float    32 または 64 ビット
uintptr  ポインタの値をそのまま格納するのに充分な大きさの符号なし整数

uint8の別名であるbyte型を除いて、数値型はサイズが同じであってもそれぞれが別の型です。これは移植時に問題が起きないようにするためです。互換性のない数値型どうしを式や代入に使用するときは変換が必要となります。たとえばint32intが、あるアーキテクチャ上で同一のサイズであったとしても、これらは同じ型ではありません。

文字列型

文字列型は文字列の値を表現します。文字列はbyteの配列のように振舞いますが、値は不変です。つまり一度作成された以降は、文字列の内容を変更できません。文字列型として事前宣言済みの型はstringです。

文字列型の要素はbyte型データを持っているため、一般的なインデックスを使ったアクセスが可能です。ただし要素のアドレスを取得することはできません。すなわちs[i]が、ある文字列のi番目のバイトであるとして、&s[i]とすることはできません。文字列の長さは、組み込み関数lenを使用して調べることができます。文字列sがリテラルであれば、文字列長はコンパイル時に定数となります。

配列型

配列は同一の型(要素型)を持つ要素を並べたものです。要素の数は長さ(length)と呼ばれます。この値はマイナス値には成り得ません。

ArrayType   = "[" ArrayLength "]" ElementType .
ArrayLength = Expression .
ElementType = Type .

配列の長さ情報は、その配列型の一部であり定数式で使うことができます。配列aの長さは、組み込み関数len(a)を使用して調べることができ、コンパイル時に定数となります。配列の要素は、0からlen(a)-1までの整数によるインデックスで指し示すことができます(§インデックス)。

[32]byte
[2*N] struct { x, y int32 }
[1000]*float64

スライス型

スライスはある配列内の連続した領域への参照であり、スライスの内容はその配列の要素の並びです。スライス型は、その要素型を持つ配列すべてのスライスの集合を表します。スライス型の値はnilをとることがあります。

SliceType = "[" "]" ElementType .

配列のように、スライスはインデックスによる指定が可能で長さを持ちます。スライスsの長さは、組み込み関数len(s)を使用して調べることができますが、配列の場合とは異なり長さは実行中に変わることがあります。要素は0からlen(s)-1までの整数によるインデックスで指し示すことができます(§インデックス)。

スライスは一度初期化されると、その要素を所有する配列との関連を常に保ちます。そのため、スライスは元となった配列および、同一の配列から作られた別のスライスとメモリを共有します。これとは対照的に、異なる配列は常に異なるメモリ領域を有します。

スライスの元になった配列は、スライスの最後の要素以降にも要素を持つことがあります。キャパシティとは範囲の大きさであり、スライスの長さと、元の配列のスライス以降の長さとの合計です。スライスから新しく『スライスする』ことによって、最大でキャパシティの値までの長さのスライスを作ることができます(§スライス)。スライスaのキャパシティは組み込み関数cap(a)で調べることができます。len()cap()の関係は次のとおりです。

0 <= len(a) <= cap(a)

初期化されていないスライスの値はnilです。nilスライスの長さとキャパシティはともに0です。初期化済みの新しいスライスを作るには組み込み関数makeを使用します。make関数はパラメータにスライスの型と長さ、オプションでキャパシティをとります。

make([]T, length)
make([]T, length, capacity)

make()は隠された配列を新たに割り当て、それを参照するスライスを返します。次のようにします。

make([]T, length, capacity)

これは配列を割り当て、そこからスライスを作成するのと同じことなので、ゆえに次の2つの例は結果として同じスライスになります。

make([]int, 50, 100)
new([100]int)[0:50]

構造体型

構造体は、フィールドと呼ばれる要素の集まりで、それぞれが名前と型を持っています。フィールド名は明示的(IdentifierList)、または暗黙的(AnonymousField)に指定されます。ブランクフィールドを除いて、フィールド名は構造体内でユニークである必要があります。

StructType     = "struct" "{" [ FieldDeclList ] "}" .
FieldDeclList  = FieldDecl { ";" FieldDecl } [ ";" ] .
FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
AnonymousField = [ "*" ] TypeName .
Tag            = StringLit .
// 空の構造体
struct {}

// 6フィールド持つ構造体
struct {
	x, y int;
	u float;
	_ float;  // パディング
	A *[]int;
	F func();
}

フィールドが型だけでフィールド名を指定せずに宣言されたときは匿名フィールドとなります。このような匿名フィールドの型は、型名Tまたは型へのポインタ*Tのように記述しなければなりません。T自体はポインタ型でないかもしれません。フィールド名を伴わないとき型名がフィールド名として扱われます。

// 匿名フィールド T1, *T2, P.T3, *P.T4を持つ構造体
struct {
	T1;        // フィールド名は T1
	*T2;       // フィールド名は T2
	P.T3;      // フィールド名は T3
	*P.T4;     // フィールド名は T4
	x, y int;  // フィールド名は x と y
}

下の宣言は、構造体内でフィールド名がユニークにならないため誤りです。

struct {
	T;         // 匿名フィールド *T と *P.T で不整合
	*T;        // 匿名フィールド  T と *P.T で不整合
	*P.T;      // 匿名フィールド  T と *T   で不整合
}

匿名フィールド内のフィールドとメソッド(§メソッドの宣言)は、その構造体直管のフィールドとメソッドへ昇格されます($セレクタ)。仮にS構造体とT型があるとすると、以下のルールが成り立ちます。

  • Sが匿名フィールドとしてTを有していれば、Sのメソッド群はTのメソッド群を含みます。
  • Sが匿名フィールドとして*Tを有していれば、Sのメソッド群は*Tのメソッド群(Tのメソッド群も含む)を含みます。
  • Sが匿名フィールドとしてTまたは*Tを有していれば、*Sのメソッド群は*Tのメソッド群(Tのメソッド群も含む)を含みます。

フィールドの宣言には、オプションで文字列リテラルを使ってタグを指定することができます。タグはそれが記述されているフィールド宣言の全フィールドの属性となります。タグはリフレクションインタフェースを使って参照できますが、それ以外は無視されます。

// TimeStampプロトコルバッファと一致した構造体
// タグの文字列でプロトコルバッファのフィールド番号を定義
struct {
	microsec  uint64 "field 1";
	serverIP6 uint64 "field 2";
	process   string "field 3";
}

ポインタ型

ポインタ型は所定の型(ベース型)の変数へのすべてのポインタの集合を表します。ポインタの値はnilをとることがあります。

PointerType = "*" BaseType .
BaseType = Type .
*int
*map[string] *chan int

関数型

関数型は、同一のパラメータと同一の戻り値を持つすべての関数の集合を表します。関数型の値はnilをとることがあります。

FunctionType   = "func" Signature .
Signature      = Parameters [ Result ] .
Result         = Parameters | Type .
Parameters     = "(" [ ParameterList ] ")" .
ParameterList  = ParameterDecl { "," ParameterDecl } .
ParameterDecl  = [ IdentifierList ] ( Type | "..." ) .

名前(IdentifierList)はパラメータリストまたは戻り値リストすべてに記述するか、またはすべて省略するかいずれかです。記述した場合、それぞれの名前がアイテム(パラメータまたは戻り値)ひとつを表します。省略した場合、それぞれの型がその型のアイテムひとつを表します。パラメータと結果リストは常に括弧でくくられます。例外として、戻り値がひとつだけで、名前がなく、括弧なしで記述された関数型でないときだけは括弧は不要です。

最後のパラメータだけは型の代わりに…と記述可能です。これは、この関数がゼロ個以上の任意の型の付加的パラメータを処理することを表します。

func ()
func (x int)
func () int
func (string, float, ...)
func (a, b int, z float) bool
func (a, b int, z float) (bool)
func (a, b int, z float, opt ...) (success bool)
func (int, int, float) (float, *[]int)
func (n int) (func (p* T))

インタフェース型

インタフェース型はメソッド群を規定します。メソッド群はインタフェース名で呼ばれます。インタフェース型の変数には、そのインタフェースの「全スーパーセットのメソッド群を持っている型」の値を格納することができます。そのような型はこのインタフェースを実装していると言えます。インタフェース型の値はnilをとることがあります。

InterfaceType      = "interface" "{" [ MethodSpecList ] "}" .
MethodSpecList     = MethodSpec { ";" MethodSpec } [ ";" ] .
MethodSpec         = MethodName Signature | InterfaceTypeName .
MethodName         = identifier .
InterfaceTypeName  = TypeName .

他のメソッド群でも同じですが、インタフェース型においてメソッドはユニークな名前を持つ必要があります。

// 単純なFileインタフェース
interface {
	Read(b Buffer) bool;
	Write(b Buffer) bool;
	Close();
}

インタフェースは複数の型に実装することができます。例えば、S1S2 の2つの型が次のメソッド群を持つ場合、

func (p T) Read(b Buffer) bool { return ... }
func (p T) Write(b Buffer) bool { return ... }
func (p T) Close() { ... }

(TS1S2を表すとして)File インタフェースはS1S2の両方に実装されます。S1S2が他のメソッドを持つか共有していても関係ありません。

型は、その型のメソッド群の一部から構成されているインタフェースすべてを実装していることになります。したがって複数の異なるインタフェースを実装することもできます。例を挙げるなら、すべての型は次の空(empty)インタフェースを実装しています。

interface{}

同様に、下のインタフェースの記述方法をみてください。ここでは型の宣言内でLockという名のインタフェースを定義しています。

type Lock interface {
	Lock();
	Unlock();
}

S1S2がこれらのメソッドを実装した場合、

func (p T) Lock() { ... }
func (p T) Unlock() { ... }

S1S2Fileインタフェースと同様にLockインタフェースも実装します。

インタフェースにはメソッドを記述する代わりに、別のインタフェース型を含むことができます。仮に Tというインタフェース名を記述したとすると、これは Tのメソッドを明示的に列挙したのと同じことになります。

type ReadWrite interface {
	Read(b Buffer) bool;
	Write(b Buffer) bool;
}

type File interface {
	ReadWrite;  // ReadWrite内のメソッドを列挙したことと同じ
	Lock;       // Lock内のメソッドを列挙したことと同じ
	Close();
}

マップ型

マップ型はある型(要素型)の要素の順序を持たない集合で、要素は別の型(キー型)のユニークなキーにより索引付けされます。マップ型の値はnilをとることがあります。

MapType     = "map" "[" KeyType "]" ElementType .
KeyType     = Type .

キーどうしの比較に使用するため、キー型においては比較演算子==!=比較演算子)が完全に実装されている必要があります。ゆえにキー型は論理値型、数値型、文字列型、ポインタ型、関数型、インタフェース型、マップ型、チャネル型である必要があります。キー型がインタフェース型のとき、比較演算子は動的なキー値を比較するために完全に定義されていなければなりません。比較できなければランタイムエラーとなります。

map [string] int
map [*T] struct { x, y float }
map [string] interface {}

要素の数は長さ(length)と呼ばれます。この値はマイナス値には成り得ません。マップmの長さは、組み込み関数len(m)を使用して調べることができ、コンパイル時に定数となります。マップ内の要素は、特殊な代入方法で実行中に追加、削除できます。

初期化されていないマップの値はnilです。空の新しいマップを作るには組み込み関数makeを使用します。make関数はパラメータにマップの型と、オプションでキャパシティのヒントをとります。

make(map[string] int)
make(map[string] int, 100)

キャパシティの初期値は指定したサイズを超えることはありません。マップは格納する項目が収まるようにサイズを広げます。

チャネル型

チャネルは同時に実行されるふたつの関数に、同期実行と特定の要素型の値を受け渡す通信機構を提供します。チャネル型の値はnilをとることがあります。

ChannelType   = Channel | SendChannel | RecvChannel .
Channel       = "chan" ElementType .
SendChannel   = "chan" "<-" ElementType .
RecvChannel   = "<-" "chan" ElementType .

作成と同時にチャネルは送受信できるようになります。変換または代入によってチャネルは送信のみ、または受信のみ行うよう強制することができます。この制約はチャネルの方向と呼ばれ、送信のみ、受信のみ、双方向(制約なし)のいずれかとなります。

chan T         // T型の値を送受信可能
chan<- float   // floatの送信のみ
<-chan int     // intの受信のみ

初期化されていないチャネルの値はnilです。初期化済みの新しいチャネルを作るには組み込み関数makeを使用します。make関数はパラメータにチャネルの型と、オプションでキャパシティをとります。

make(chan int, 100)

キャパシティは要素数であり、チャネルのバッファサイズを指定します。キャパシティがゼロより大きいとき、チャネルは非同期になり、バッファがいっぱいになるまで、送信はブロックすることなく成功します。キャパシティがゼロまたは指定しなかったときは、通信は送信・受信側双方が準備ができているときだけ成功します。

チャネルは組み込み関数closeとclosedを使ってクローズ、およびクローズされたか確認することができます。

The Go Programming Language Specificationの翻訳、4回目です。
前回までの訳はGo言語仕様[日本語訳]にまとめてあります。


定数

定数にはブーリアン定数、整数定数、浮動小数点定数、文字列定数があります。整数定数と浮動小数点定数はまとめて数値定数とも呼ばれます。

定数の値は整数リテラル浮動小数点リテラル文字リテラル文字列リテラル、定数を示す識別子、定数式unsafe.Sizeofのような組み込み関数からの戻り値、配列のcapまたはlen、文字列定数のlenによって表されます。ブーリアンの真理値は事前宣言済み定数trueおよびfalseによって表されます。事前宣言済み識別子iotaは整数リテラルを表します。

数値定数はサイズを持たず、またオーバーフローすることがない任意精度の値を表します。

定数にはを持つもの、持たないものがあります。リテラル定数、truefalseiota、および”定数式内の全オペランドが型を持たない定数”のときは、定数は型を持ちません。

定数は定数の宣言または変換によって明示的に、または変数の宣言代入のオペランドで使われるときに暗黙的に、型が付与されます。ただし定数の値が、各型の値を正確に表現することができなければエラーとなります。例えば、3.0はすべての整数型もしくは浮動小数点型にすることができます。しかし、2147483648.0(1<<31と同値)はfloat32型、float64型、uint32型にはできますが、int32型やstring型にはできません。

実装の制約:コンパイラは数値定数の内部表現に最小でもマシンの倍のビット数を使います。浮動小数点の値については、仮数部と指数部それぞれが倍になります。

The Go Programming Language Specificationの翻訳、3回目です。
前回までの訳はGo言語仕様[日本語訳]にまとめてあります。


字句要素

コメント

コメントには2種類の書式があります。
ひとつ目の書式は文字シーケンス//で始まり、行の終わりまでがコメントとなります。ふたつ目は文字シーケンス/*で始まり、文字シーケンス*/までがコメントとなります。コメントを入れ子にすることはできません。

トークン

トークンには識別子、キーワード、演算子と区切り文字、リテラルの4つのクラスがあります。
ホワイトスペースはスペース(U+0020)、水平タブ (U+0009)、キャリッジリターン (U+000D)、改行 (U+000A)です。ホワイトスペースは、それがなければ一つのトークンとして結合されてしまうトークンを分割するほかは無視されます。コメントはホワ イトスペースと同等に扱われます。入力をトークンに分割する際、次のトークンは長い文字列シーケンスから成る有効なトークンです。

識別子

識別子は変数や型といったプログラムの実体に対し名前をつけます。
識別子は一文字以上の字(レター)と数字から構成されます。先頭一文字は字でなくてはなりません。

identifier = letter { letter | unicode_digit } .
a
_x9
ThisVariableIsExported
αβ

いくつかの識別子は事前宣言済みです。

キーワード

下に示すキーワードは予約されているため、識別子としては使用できません。

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

演算子と区切り文字

下に示す文字シーケンスは、演算子、区切り文字および、その他の特別なトークンです。

+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=

整数リテラル

整数リテラルは整数定数を表す数字の並びです。
10進数以外の値を表すにはプレフィックスをつけます。0は8進数で、0xまたは0Xを付けると16進数になります。16進数の場合、文字a~fA~Fを10~15の値を表すために使います。

int_lit     = decimal_lit | octal_lit | hex_lit .
decimal_lit = ( "1" ... "9" ) { decimal_digit } .
octal_lit   = "0" { octal_digit } .
hex_lit     = "0" ( "x" | "X" ) hex_digit { hex_digit } .
42
0600
0xBadFace
170141183460469231731687303715884105727

浮動小数点リテラル

浮動小数点リテラルは浮動小数点定数を表す小数で、整数部・小数点・小数部・指数部を持ちます。
整数部と小数部は10進数から成ります。指数部はeまたはEと、それに続く符号(オプション)と10進数の指数です。
整数部と分数部のどちらかは省略でき、また小数点か指数部のどちらかも省略できます。

float_lit = decimals "." [ decimals ] [ exponent ] |
            decimals exponent |
            "." decimals [ exponent ] .
decimals  = decimal_digit { decimal_digit } .
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .
0.
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5

文字リテラル

文字リテラルは整数定数、概して一文字以上の文字をシングルクォートでくくりユニコードのコードポイントを表現します。

クォート内にはシングルクォートと改行を除くどんな文字も記述できます。バックスラッシュを使用したマルチ文字シーケンスの各書式を使ってエンコードすることで、シングルクォート文字自体も表せます。

クォートを使うと簡単に一文字を表すことができます。これはGo言語のソースがUTF-8エンコードされたユニコード文字であり、UTF-8エンコードされている複数のバイト列であってもひとつの整数値を表せるからです。
たとえば、リテラル'a'はリテラルa、ユニコード U+0061、値0x61を表す1バイトの値です。一方'ä' はリテラルa-dieresis、 U+00E4、値0xe4を表しますが、UTF-8エンコードでは2バイト (0xc3 0xa4)です。

バックスラッシュによるエスケープを使って任意の値をアスキー文字として表すことができます。定数として整数値を表すには次の4通りの方法があります。\xに続いた2つの16進数文字、\uに続いた4つの16進数文字、\Uに続いた8つの16進数文字、\に続いた3つの8進数文字です。それぞれのリテラルの値は、基数に対応した数字で表される値です。

これらが表す値はすべて整数ですが、値の範囲がそれぞれ異なります。8進数のエスケープで表す値は0-255の範囲内でなければなりません。16真数のエスケープはその書式を満たす0-255が範囲です。\u\Uはユニコードのコードポイントを表すため、いくつかの値は不正な値となります。特に0x10FFFFより大きい数と上位サロゲートは不正な値です。

バックスラッシュで特定の一文字をエスケープすることで特別な値を表します。

\a   U+0007 alert or bell
\b   U+0008 backspace
\f   U+000C form feed
\n   U+000A line feed or newline
\r   U+000D carriage return
\t   U+0009 horizontal tab
\v   U+000b vertical tab
\\   U+005c backslash
\'   U+0027 single quote  (valid escape only within character literals)
\"   U+0022 double quote  (valid escape only within string literals)

これ以外のバックスラッシュで始まるシーケンスは文字リテラル内では不正となります。

char_lit         = "'" ( unicode_value | byte_value ) "'" .
unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
byte_value       = octal_byte_value | hex_byte_value .
octal_byte_value = `\` octal_digit octal_digit octal_digit .
hex_byte_value   = `\` "x" hex_digit hex_digit .
little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
                           hex_digit hex_digit hex_digit hex_digit .
escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
'a'
'ä'
'本'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'

文字列リテラル

文字列リテラルは結合された文字シーケンスから成る文字列定数を表します。
文字列リテラルには未加工(raw)文字列リテラルと、解釈有(interpreted)文字列リテラルの2通りの記述方法があります。

未加工文字列リテラルは、バッククォート``で囲まれた文字シーケンスです。クォート内にはバッククォート以外の文字すべてを記述できます。この未加工文字列リテラルの示す値は、クォート内の解釈されない文字から成る文字列で、バックスラッシュも特別な意味を持たず、また文字列は複数行にまたがることも可能です。

解釈有文字列リテラルはダブルクォート""で囲まれた文字シーケンスです。クォートで囲まれたテキストは複数行にまたがることはできず、文字リテラルとおなじくバックスラッシュによるエスケープを解釈した結果がリテラルの値となります。(\'は使えませんが、\"は使用できます。)3つの数字から成る8進数(\000) 、2つの数字から成る16進数 (\x00)のエスケープは個々のバイトを表します。他のすべてのエスケープは(マルチバイトも含め) UTF-8エンコードされた個別の文字を表します。したがって文字列リテラル \377\xFFは、1バイトの値0xFF=255を表します。一方 ÿ\u00FF\U000000FF、\xc3\xbfは、文字U+00FFをUTF8エンコーディングした値である2バイト0xc3 0xbfを表します。

文字列シーケンスを並べたものは結合されて、ひとつの文字列となります。

StringLit              = string_lit { string_lit } .
string_lit             = raw_string_lit | interpreted_string_lit .
raw_string_lit         = "`" { unicode_char } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
`abc`  // same as "abc"
`\n
\n`    // same as "\\n\n\\n"
"\n"
""
"Hello, world!\n"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"
"Alea iacta est."
"Alea " /* The die */ `iacta est` /* is cast */ "."  // same as "Alea iacta est."

次の例は、すべて同じ文字列を表しています。

"日本語"                                 // UTF-8 input text
`日本語`                                 // UTF-8 input text as a raw literal
"\u65e5\u672c\u8a9e"                    // The explicit Unicode code points
"\U000065e5\U0000672c\U00008a9e"        // The explicit Unicode code points
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // The explicit UTF-8 bytes

ソースコード内に、アクセントとアルファベットを結合した場合のように2つのコードポイントから成る「文字リテラル」があるとエラーとなります。こ れは文字リテラルがひとつのコードポイントを表すためです。ただし「文字列リテラル」には2つのコードポイントから成る文字を記述できます。

The Go Programming Language Specificationの翻訳、2回目です。
前回の訳はGo言語仕様[日本語訳]にまとめてあります。


ソースの文字コード

ソースの文字コードは、UTF-8でエンコードされたユニコード文字です。テキストは正規化されないため、あるアクセント付きコードポイントは、それと同 じ文字ではあるがアクセント記号とアルファベットを結合して造られた文字とは別のものとして扱われます。これらは2つのコードポイントとみなされます。
このドキュメントでは「ユニコードのコードポイント」と記述する代わりに、文字(キャラクタ)という言葉を使用します。

各コードポイントはそれぞれ異なる文字です。たとえば同じアルファベットの文字でも大文字・小文字が違えば別の文字として扱われます。

文字

次の書き方は、特定のユニコード文字クラスを示すときに用いられます。

unicode_char   = /* an arbitrary Unicode code point */ .
unicode_letter = /* a Unicode code point classified as "Letter" */ .
unicode_digit  = /* a Unicode code point classified as "Digit" */ .

The Unicode Standard 5.1のセクション4.5 「General Category—Normative」において、文字カテゴリセットが定義されています。
Go言語ではこれらカテゴリのうちLu, Ll, Lt, Lm, Loをユニコード字(レター)、Ndをユニコード数字として扱います。

字と数字

アンダースコア_ (U+005F)は、字(レター)とみなされます。

letter        = unicode_letter | "_" .
decimal_digit = "0" ... "9" .
octal_digit   = "0" ... "7" .
hex_digit     = "0" ... "9" | "A" ... "F" | "a" ... "f" .