【Part2】Go言語(golang)の基本とTips

環境

  • Windows 10
  • golang1.18
  • VSCode
  • Docker
masayan
masayan

以下のドキュメントは一読されることをおすすめします。

https://go.dev/doc/effective_go

本シリーズの記事で説明する内容

  1. きほんのき
  2. ファイル、クラス等の命名規則や慣習
  3. 環境構築
  4. モジュールのimport
  5. 変数定義と代入
  6. ポインタ
  7. 配列・スライス
  8. マップ
  9. 繰り返し
  10. 条件分岐
  11. 関数
  12. ジェネリクス
  13. クラスの作り方(正確にはクラスではない)
  14. インターフェース
  15. 単体テスト
  16. フォーマット
  17. その他Tips
masayan
masayan

本記事(part2)では、上記の5~8について説明します

変数定義と代入

  • 宣言のみで代入は行わない
var name string
  • 宣言と同時に代入
var name string = "tanaka"
masayan
masayan

省略記法としてコロンイコール:=を使用できます。varと型宣言を省略できます

name := "suzuki"

ポインタ

ポインタ基礎

  • ポインタは、変数などの値の型情報+メモリアドレスのこと
  • 具体的には、こういうやつです。→ 0xc0000ac018

ポインタ型

  • 型の前に*をつけるとポインタ型を定義できる
  • 初期値はnil
  • &(アドレス演算子)を変数の前に付けることで任意の型からポインタ型を定義できる

ポインタ変数

  • ポインタ型が格納された変数のことをポインタ変数という
  • ポインタ変数にはその変数のメモリアドレスが格納されている
  • ポインタ変数をprintで出力すると&がつく
// 言語の構造体
type Language struct {
  Name string
}

// lがポインタ変数、*LanguageがLanguageポインタ型
var l *Language

l = &Language{
  Name: "韓国語",
}

fmt.Println(l) // &{韓国語}
  • ポインタ変数を操作することで、ポインタが指す変数の値を直接変更することが可能
  • 逆に、値渡しだともとの変数は変更されない
// 言語の構造体
type Language struct {
    Name string
}

// ①値渡しで代入(つまり、コピーが代入される)
lang := Language{
    Name: "英語",
}
fmt.Println(lang)

// ②さらにlang2にlangを値渡しで代入(つまり、コピーが代入される)
lang2 := lang
lang2.Name = "フランス語"
fmt.Println(lang) // 値渡しなので、元のlangは変更されない(フランス語と出力されない)

// ③ポインタ渡し(参照渡し)で代入(つまり、変更すると参照元の変更される)。langのメモリアドレスが格納される
lang3 := &lang
lang3.Name = "ドイツ語"
fmt.Println(lang) // ポインタ渡し(参照渡し)なので、元のlangは変更される(英語ではなく、ドイツ語と出力される)

//① {英語}
//② {英語}
//③ {ドイツ語}

デリファレンス

  • ポインタ変数を出力すると、前述の通りメモリアドレスが出力されるが、ポインタ変数に * を付けて出力すると、そのポインタ変数が保持しているアドレスに書き込まれている値を直接取得できる

ポインタの使いどころ

  • 参照先の値ごと変更する必要のある箇所
    • 例えば、構造体内のメソッドで、構造体のフィールドの情報を変更するとき(つまりセッター)
    • コンストラクタの返り値

などなど

配列・スライス

配列

  • 固定長
  • 初期化のしかた
    • 要素数を指定して、その要素を{}内に指定する
      array := [5]int {1, 2, 3, 4, 5}
  • 要素の追加
    • 固定長なので追加不可

スライス

  • 可変長
  • 初期化のしかた
    • 空のスライスで初期化
      slice := []int {}
    • 初期値ありのスライスで初期化
      slice := []int{1, 2, 3, 4, 5}
  • 要素の追加
    • appendで追加可能
    • appendの第一引数には追加対象のスライスを、第二引数には追加する要素を指定する
    • appendの返り値は、第一引数のスライスのコピー
slice1 := []int{1, 2, 3, 4, 5} 
slice2 = append(slice1, 6) // ←のように追加後のslice1をslice2に代入すると、元のslice1も変わる
    • appendは非破壊メソッド

マップ

  • 連想配列
  • 初期化のしかた
    var 変数名 = map[キーのデータ型]値のデータ型{}
    
    var userData = map[string]string{}
    
    // mapのスライスの初期化
    var userDataList = []map[string]string{}
  • mapの追加
    • mapへの追加
      • userData["name"] = "田中”のように、キーを指定して追加する
    • mapのスライスへの追加
      var userDataList = []map[string]string{}
      var userData = map[string]string{}
      userData["id"] = "1"
      userData["name"] = "田中"
      userDataList = append(userDataList, userData)
      fmt.Println(userDataList) // [map[id:1 name:田中]]

以上です。次回partでは9.~17.までの説明を行いたいと思います

    Go学習におすすめの書籍

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