Go言語入門:言語仕様 -Vol.73-

スポンサーリンク
Go言語入門:言語仕様 -Vol.73- 用語解説
Go言語入門:言語仕様 -Vol.73-
この記事は約4分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、Go言語の言語仕様について解説しています。

スポンサーリンク

背景

Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。

言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。

そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。

言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!

スライス式(Slice expressions)

スライス式は、文字列、配列、配列へのポインタ、またはスライスのオペランドから、部分文字列またはスライスを構築する。2つのバリエーションがある。下限と上限を指定する単純形式と、容量の境界も指定する完全形式である。

オペランドの型が型パラメータである場合、その型集合に文字列型が含まれない限り、型集合内のすべての型は同じ基底型を持たなければならず、スライス式はその型のオペランドに対して有効でなければならない。型集合に文字列型が含まれる場合、基底型が []byte のバイトスライスも含むことができる。この場合、スライス式は string 型のオペランドに対して有効でなければならない。


解説

スライス式ってなに?

スライス式は a[i:j] の形で、元のデータから一部を切り出す構文です。Go では日常的に使われますね。

s := []int{10, 20, 30, 40, 50}
sub := s[1:4]   // [20, 30, 40]

切り出せる対象は4種類です。

  • 文字列(string)→ 部分文字列が得られる
  • 配列([N]T)→ スライスが得られる
  • 配列へのポインタ(*[N]T)→ スライスが得られる
  • スライス([]T)→ スライスが得られる
// 文字列から部分文字列
str := "hello"
fmt.Println(str[1:4])  // "ell"

// 配列から切り出すとスライスになる
arr := [5]int{10, 20, 30, 40, 50}
sl := arr[1:4]         // []int{20, 30, 40}

// スライスから切り出しても当然スライス
s := []int{10, 20, 30, 40, 50}
sub := s[1:4]          // []int{20, 30, 40}

2つの形式

原文で触れられている2つのバリエーションは次のものです。

単純形式(下限と上限)

a[low:high]

完全形式(容量の境界も指定)

a[low:high:max]

完全形式を使うと、切り出したスライスの容量(cap)まで制御できます。これは次の節以降で詳しく説明されるので、ここでは「2種類ある」とだけ押さえておけば大丈夫です。

型パラメータとの組み合わせ

ジェネリクスの話は少しややこしいですが、ポイントは2つです。

1. 型集合の全員が同じ基底型を持つ必要がある

型パラメータ P の型集合に複数の型が含まれる場合、すべてが同じ基底型でないとスライス式が書けません。

// OK:どちらもスライスで、要素型が同じ
type MySlice []int

func Head[S ~[]int](s S) S {
    return s[:1]  // スライス式が使える
}

2. 文字列と []byte だけは特別扱い

普段、文字列と []byte は別の型ですが、スライス式の文脈では一緒に扱えます。

// 文字列と []byte を両方受け付けるジェネリック関数
func Prefix[S ~string | ~[]byte](s S, n int) S {
    return s[:n]
}

Prefix("hello", 3)             // "hel"
Prefix([]byte("hello"), 3)     // [104 101 108]

文字列と []byte はどちらも「バイトの並び」として扱えるため、この組み合わせだけ例外的に許されているわけですね。strings パッケージと bytes パッケージの機能を共通化したいときなどに役立ちます。


この節自体は導入部分で、具体的なルールは次の「単純形式」と「完全形式」の節で詳しく説明されます。

おわりに 

本日は、Go言語の言語仕様について解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました