【プログラム初心者向け】golangのプログラミングノート

# はじめに
golangを学ぶにあたって、基本的な文法をまとめてみました。
超基本的な内容です。随時、アップデートします。


# 環境構築(Mac)
```:homebrewアップデート
brew update
```
```:goインストール
brew install go
```
```:goバージョン確認
go version
```

# 実行
```:hello.go
package main

import ("fmt")

func main(){
    fmt.Println("おはよう")
    fmt.Println("こんにちは")
    fmt.Println("こんばんは")
}
```
・Goのプログラムは、何らかのパッケージに属している必要がある
・Goのプログラムは、そのうち1つは、必ずmainパッケージに属している必要がある
・ここでは、プログラム内で使う「fmt」というパッケージをインポートしている
・fmtパッケージをインポートすることで、fmtパッケージの中にある関数などを使えるようになる
・fmtパッケージには、文字列を表示させる関数が入っている
・Goでは、fmtパッケージのようなよく使う関数をひとまとめにして、「パッケージ」という形で提供している
・ここでは、mainという名前の関数を定義している
・Goのプログラムは、mainパッケージの中にあるmain関数からプログラムがスタートする
・プログラムがスタートする場所のことを、エントリーポイントと呼ぶ

```:ビルド
go build hello.go
```

```:実行
./hello
```

```:実行結果
おはよう
こんにちは
こんばんは
```
# 変数
### 変数とは
・変数は例えるなら箱のこと
・変数があることで、文字や数字などのデータを変数に入れておくことができる
・また、変数を必要な時に取り出すことができる
・変数にデータを入れることを「代入」といい、取り出すことを「参照」という
・変数には名前をつけることができ、変数名という
・変数を作ることを「変数を宣言する」という
・初めて変数にデータを入れることを「変数の初期化」という
### 変数の宣言
```
package main

import ("fmt")

func main(){
    var num int
    num = 1
	fmt.Println(num)
}
```
・ここでは整数などの値を代入するnumという変数を宣言している
・変数を宣言するときは、まずvarと書く
・varの次に変数名を記述
・変数名のあとに、変数に代入するデータの種類を記述
・このデータの種類のことを「データ型」という
・ここでは、1という値を代入するので、値型の「int型」使用する
・ここでは、変数numに1という整数を代入している
・変数へ代入するときは、イコールを使う
文字列や変数の中を参照するには、Println(プリントライン)関数を使う
・前項目ではダブルクォテーションで文字列を囲んだが、今回は変数の中を表示したいので、変数をそのまま記述する

```:実行結果
1
```

```:変数の宣言と同時に代入
    var num = 1
	fmt.Println(num)
```
・変数の宣言と同時に代入することもできる
・また、データ型は省略することもできる
・Goが自動的にデータ型を判断するから

```:変数の宣言と同時に代入(さらにシンプルな記述)
    num := 1
	fmt.Println(num)
```
・変数の宣言と同時に代入する際は、さらにシンプルに書くことができる
・変数名、コロン、イコール、代入したい値の順に記載する
・このコロンイコールの書き方が、Goでよく使われる変数の宣言方法
・この記述は関数外では使用できない

### 変数名のルール
```
package main

import ("fmt")

func main(){
    num := 1
    num01 := 2
    num_01 := 3

    fmt.Println(num)
    fmt.Println(num01)
    fmt.Println(num_01)
}
```
・変数名に使える文字には、ルールがある
・変数名には、アルファベット、数字、アンダースコア( _ )が使える
・変数名は、数字から始めることが出来ない
・アンダースコア以外に記号を使うことができない
・大文字と小文字は区別される
・予約語は変数名にすることができない
・予約語とは、「return」「import」「for 」「package」など、プログラミング言語ですでに役割が決まっている単語のこと

```:実行結果
1
2
3
```

# データ型
### データ型とは
・データ型とは、変数に入れるデータの種類のこと
・Goでは、変数にデータを入れるときに、データ型を指定する必要がある
・このようなプログラミング言語のことを静的型付け言語という
・静的型付け言語には、Go、Java、Kotlin、C言語などがある
・Goのデータ型は数値型、文字列型、ブール型がある
・一方、変数にデータを入れるときに、データ型を指定する必要がなく、自動的にデータ型を判断してくれる言語がある
・このような言語のことを動的型付け言語という
・動的型付け言語には、Ruby、Python、JavaScript、PHPなどがある

### Goの数値型
・数値型には、整数型と小数点型がある
・整数型には「Int8」「Int16」「Int32」「Int64」がある
・「Int8」が扱える桁数が小さく、「Int64」が扱える桁数が一番大きい
・後ろの数字を省略してIntとすることもできる
・これは、実装するOSやCPUに依存した整数型
・通常はこのInt型で問題ない
・小数点型には、「float32」「float64」
・「float32」より「float64」の方が、小数点以下の扱える桁数が大きい
・通常は、「float64」で問題ない

```:数値型サンプルコード
package main

import (
	"fmt"
)

func main(){
        num01 := 1
        var num02 int = 1234567890
        num03 := 1.234
        var num04 float64 = 1.23456789

        fmt.Println(num01)
        fmt.Println(num02)
        fmt.Println(num03)
        fmt.Println(num04)
}
```

```:実行結果
1
1234567890
1.234
1.23456789
```
```:データ型の確認
package main

import (
        "fmt"
        "reflect"
)

func main() {
        num01 := 123
        var num02 int = 1234567890
        num03 := 1.23
        var num04 float64 = 1.23456789

        fmt.Println(reflect.TypeOf(num01))
        fmt.Println(reflect.TypeOf(num02))
        fmt.Println(reflect.TypeOf(num03))
        fmt.Println(reflect.TypeOf(num04))
}
```
・Goのデータ型は、「reflect（リフレクト）」のパッケージの「TypeOf（タイプオフ）」を使用して確認する事ができる
・importに「reflect」を追加する

```:実行結果
int
int
float64
float64
```
### Goの文字列型
・文字列型は「string型」ともいう
・文字列はダブルクォーテーションでくくる

```:文字列型のサンプルコード
package main
import (
        "fmt"
        "reflect"
)

func main(){
        var string_a string = "Hello,World!"
        string_b := "Hello,World!"
        fmt.Println(string_a)
        fmt.Println(reflect.TypeOf(string_a))
        fmt.Println(string_b)
        fmt.Println(reflect.TypeOf(string_b))

}
```
```:実行結果
Hello,World!
string
Hello,World!
string
```

### Goのブール型
・ブール型は、Boolean型（ブーリアン型）ともいう
・ブール型は、TrueまたFalseの2つのうち、どちらか1つを持つ型のこと

```:ブール型のサンプルコード
package main
import (
        "fmt"
        "reflect"
)

func main(){
        a := 10
        b := 1
        var num_bool bool = a > b

        fmt.Println(num_bool)
        fmt.Println(reflect.TypeOf(num_bool))
}
```
```:実行結果
true
bool
```
```:ブール型のサンプルコード(データ型の省略とFalse)
package main
import (
        "fmt"
        "reflect"
)

func main(){
        a := 10
        b := 1
        num_bool := a < b

        fmt.Println(num_bool)
        fmt.Println(reflect.TypeOf(num_bool))
}
```
```:実行結果
false
bool
```

# 配列
### 配列とは
・配列とは、複数のデータを格納することができるデータ型
・変数は「箱」と説明なのに対して、配列は複数のデータを入れることができる「ロッカー」のイメージ
・1列の配列のことを1次元配列といい、2列以上ある配列は多次元配列という
・配列の1つ1つの箱のことを要素といい、箱の数を要素数という
・配列のそれぞれの要素には、インデックス(添字)という場所の情報が割り当てられている
### 配列の宣言
```:配列の書き方
変数 := [要素数]データ型｛データ1,データ2,…｝
```
```:配列のサンプルコード
package main
import "fmt"
func main() {
  a := [3] string {"sato", "suzuki", "takahashi" }

  fmt.Println(a[0])
  fmt.Println(a[1])
  fmt.Println(a[2])
}
```
```:実行結果
sato
suzuki
takahashi
```
### 配列の要素の変更方法
```:susukiをtanakaに変更
package main
import "fmt"
func main() {
  a := [3] string {"sato", "suzuki", "takahashi" }
  a[1] = "tanaka"

  fmt.Println(a[0])
  fmt.Println(a[1])
  fmt.Println(a[2])
}
```
```:実行結果
sato
tanaka
takahashi
```
### 要素数を省略した記述方法
```:要素数を省略した記述方法
配列変数 := […]データ型｛データ1,データ2,….｝
```
```:要素数を省略したサンプルコード
package main
import "fmt"
func main() {
  a := [...] string {"sato", "suzuki", "takahashi" }
  a[1] = "tanaka"

  fmt.Println(a[0])
  fmt.Println(a[1])
  fmt.Println(a[2])
}
```
```:実行結果
sato
tanaka
takahashi
```
### 多次元配列
```:多次元配列のサンプルコード
package main
import "fmt"
func main() {
  a := [2] [2] string{{"sato", "suzuki"}, {"takahashi", "tanaka"}}

  fmt.Println(a[0][0])
  fmt.Println(a[0][1])
  fmt.Println(a[1][0])
  fmt.Println(a[1][1])
}
```
```:実行結果
sato
suzuki
takahashi
tanaka
```

# 演算子
### 演算子とは
・足し算、引き算などの四則演算や2つの値の大小を比較するときに使う記号のこと

### 算術演算子
・算術演算子とは、足し算、引き算、掛け算、割り算などをするための演算子のこと

```:算術演算子を使用したサンプルコード
　package main
import "fmt"
func main(){
    x := 10
    y := 2

    fmt.Println(x + y)
    fmt.Println(x - y)
    fmt.Println(x * y)
    fmt.Println(x / y)
    fmt.Println(x % y)
}
```
```:実行結果
12
8
20
5
0
```
### 関係演算子
・2つの値の関係が正しいか正しくないか判断させる演算子のこと

```:関係演算子を使用したサンプルコード（True）
package main
import "fmt"
func main(){
    x := 10
    y := 2

    fmt.Println(x > y)
}
```
```:実行結果
true
```
```:関係演算子を使用したサンプルコード（False）
package main
import "fmt"
func main(){
    x := 10
    y := 2

    fmt.Println(x < y)
}
```
```:実行結果
false
```
・ 以上、以下の場合は「>=」「<=」を使用する

```:関係演算子を使用したサンプルコード（等価）
package main
import "fmt"
func main(){
    x := 10
    y := 2

    fmt.Println(x == y)
    fmt.Println(x != y)
}
```
```:実行結果
false
true
```
### 論理演算子
・複数の条件を判断させる演算子のこと
・日本語でいうと「かつ」とか「または」のこと
・英語でいうとandとorのこと
・and条件は&&が2つ、or条件は縦線の||（パイプライン）が2つ

```:論理演算子を使用したサンプルコード(and条件<かつ>)
package main
import "fmt"
func main(){
    x := 8
    y := 3

    fmt.Println(x >= 5 && x <= 10)
    fmt.Println(y >= 5 && y <= 10)

}
```
```:実行結果
true
false
```
```:論理演算子を使用したサンプルコード(or条件<もしくは>)
package main
import "fmt"
func main(){
    x := 8
    y := 3

    fmt.Println(x == 3 || y == 3)
    fmt.Println(x == 1 || y == 1)
}
```
```:実行結果
true
false
```
### 代入演算子
・今まで変数に代入するときに使っていた「=」は代入演算子という
・代入する時に、足し算や引き算を同時にすることができる
・足し算、引き算などと組み合わせて代入する演算子のことを複合代入演算子という

```:代入演算子を使用したサンプルコード
package main
import "fmt"
func main(){

　　　　　　　//　代入演算子
    x := 8
    y := 12
    z := 20

　　　　　　　　// 複合代入演算子
　　　　　　　　x += 10
    z += y

    fmt.Println(x)
    fmt.Println(z)
}
```
```:実行結果
18
32
```
### インクリメントとデクリメント
・インクリメントは値を「1」増やす演算子
・インクリメントは「変数名++」と書く
・デクリメントは、値を「1」減らす演算子
・デクリメントは「変数名--」と書く

```:インクリメントとデクリメントを使用したサンプルコード
package main
import "fmt"
func main(){

    x := 8
    y := 8

    x ++
    y -- 

    fmt.Println(x)
    fmt.Println(y)
}
```
```:実行結果
9
7
```

# 条件分岐
### 分岐処理とは
・条件分岐とは、条件に合致する場合は「処理A」、そうじゃないときは「処理B」を実行するようなことができる

## if文

```:if文の記述方法
if 条件 {
　条件を満たしたときの処理
}
```
・波括弧の中に条件を満たしたときの処理を記述する
・この部分はインデントを空ける

```:if文サンプルコード(条件が真の場合)
package main
import "fmt"
func main(){
  age := 22

  if age >= 20 {
    fmt.Println("adult")
  }
}
```
```:実行結果
adult
```
```:if文サンプルコード(条件が偽の場合)
package main
import "fmt"
func main(){
  age := 18

  if age >= 20 {
    fmt.Println("adult")
  }
}
```
```:実行結果
   //何も表示されない
```
### if ~ else文

```:if〜else文の記述方法
if 条件A {
　条件Aを満たしたときの処理
} else {
　条件を満たさないときの処理
}
```

```:if~else文のサンプルコード
package main

import "fmt"

func main() {
        age := 18

        if age >= 20 {
                fmt.Println("adult")
        } else {
                fmt.Println("child")
        }
}
```
```:実行結果
child
```
###if ~ else if ~ else文

```:if~elif~else文の記述方法
if 条件A {
　条件Aを満たしたときの処理
} else if 条件B {
　条件Bを満たしたときの処理
} else {
　条件を満たさないときの処理
}
```
```::if~elif~else文のサンプルコード
package main

import "fmt"

func main() {
        age := 0

        if age >= 20 {
                fmt.Println("adult")
        } else if age == 0 {
                fmt.Println("baby")
        } else {
                fmt.Println("child")
        }
}
```
```:実行結果
baby
```
### 簡易文付きif文
・if文の中に、変数を宣言したり、変数に代入したり、四則演算の計算など簡易的な文を記述することができる

```:簡易文付きif文の記述方法
if 簡易文 ; 条件A {
　条件Aを満たしたときの処理
} else if 条件B {
　条件Bを満たさないときの処理
} else {
　条件を満たさないときの処理
}
```
```:簡易文付きif文のサンプルコード
package main

import "fmt"

func main() {

        if age := 0 ; age >= 20 {
                fmt.Println("adult")
        } else if age == 0 {
                fmt.Println("baby")
        } else {
                fmt.Println("child")
        }
}
```
```:実行結果
baby
```
```:簡易文付きif文(四則演算)のサンプルコード
package main
import "fmt"
func main(){

   x := 10
   y := 12

  if  age := x+y ; age >= 20 {
    fmt.Println("adult")
  } else if age == 0 {
    fmt.Println("baby")
  } else {
    fmt.Println("child")
  }
}
```
```:実行結果
adult
```
・簡易文は、if文の中でなければ使うことができない

# 繰り返し
### 繰り返しとは
・プログラムの基本的な動きは「順次」「分岐」「繰り返し」の3つ
・繰り返しとは、決まった回数や条件を満たしてれば、同じ処理を実行するプログラム構造のこと
・Go言語の繰り返し処理はfor文だけで、while文はない

### for文

```:for文の記述方法
for スタート値; 継続条件; 増減式{
　繰り返し中に実行する処理
}
```
```:for文のサンプルコード
package main
import "fmt"
func main(){

  for i :=  0; i <= 4; i ++ {
    fmt.Println(i);
  }
}
```
```:実行結果
0
1
2
3
4
```
### break
・break文は、ある条件にあてはまったとき、繰り返し処理を終了させることができる

```:for文のサンプルコード(break)
package main
import "fmt"
func main(){

  for i :=  0; i <= 4; i ++ {
    if i == 3  {
      break;
    }
    fmt.Println(i);
  }
}
```
```:実行結果
0
1
2
```
### continue
・continue文は、繰り返し処理をしているときに、ある条件にあてはまったときにその処理をスキップさせることができる

```:for文のサンプルコード(continue)
package main
import "fmt"
func main(){

  for i :=  0; i <= 4; i ++ {
    if i == 3 {
      continue;
    }
    fmt.Println(i);
  }
}
```
```:実行結果
0
1
2
4
```
### for文のネスト
・for文の中にfor文を入れることもできる
・for文の中にfor文が入っている構造のことをfor文のネストという

```:for文のサンプルコード(ネスト)
package main
import "fmt"
func main(){
  for i :=  0; i <= 2; i ++ {
    for j :=  0; j <= 2; j ++ {
      fmt.Println(i, "-", j); 
    }
  }
}
```
```:実行結果
0 - 0
0 - 1
0 - 2
1 - 0
1 - 1
1 - 2
2 - 0
2 - 1
2 - 2
```
### 配列とfor文

```:配列とfor文のサンプルコード
package main
import "fmt"
func main(){
  arr := [...]int{2,4,6,8,10}

  for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
  }
}
```
```:実行結果
2
4
6
8
10
```
```:配列とfor文のサンプルコード(配列の合計値を出す)
package main

import "fmt"

func main() {
        arr := [...]int{2, 4, 6, 8, 10}
        sum := 0

        for i := 0; i <= 4; i++ {
                sum += arr[i]
        }
        fmt.Println(sum)
}
```
```:実行結果
30
```
### 2つめのfor文の書き方
・スタート値、継続条件、増減式がなくてもfor文を書くことができる

```:2つめのfor文のサンプルコード(無限ループ)
package main

import "fmt"

func main() {
        i := 0
        for {
                fmt.Println(i)
        }
}
```
```:実行結果
0
0
0
0
0
・
・
・
無限に0が表示される
```
```:2つめのfor文のサンプルコード(継続条件のみ。インクリメントはfor文の中に記述。)
package main

import "fmt"

func main() {
        i := 0
        for i <= 4 {
                fmt.Println(i)
                i++
        }
}
```
```:実行結果
0
1
2
3
4
```
### 3つめのfor文の書き方
・条件を満たしたら、breakするように記述できる

```:3つめのfor文のサンプルコード
package main

import "fmt"

func main() {
        i := 0
        for {
                fmt.Println(i)
                if i == 4 {
                        break
                }
                i++
        }
}
```
```:実行結果
0
1
2
3
4
```

# 関数
### 関数の定義方法

```:関数の定義方法
func 関数名( ) {
実行する処理
}
```
```:sayHello関数のサンプルコード
package main

import "fmt"

func sayHello() {
        fmt.Println("Hello World!")
}

func main() {
        sayHello()
}
```
```:実行結果
Hello World!
```
```:sayHello関数のサンプルコード(3回実行)
package main
import "fmt"

func sayHello() {
    fmt.Println("Hello World!")
}

func main() {
    sayHello()
    sayHello()
    sayHello()
}
```
```:実行結果
Hello World!
Hello World!
Hello World!
```
```:sayHello関数のサンプルコード(引数あり。引数Goodmorningを渡す。)
package main

import "fmt"

func sayHello(greeting string) {
        fmt.Println(greeting)
}

func main() {
        sayHello("Good morning")
}
```
```:実行結果
Good morning
```
```:sayHello関数のサンプルコード(引数あり。引数Goodeveningを渡す。)
package main

import "fmt"

func sayHello(greeting string) {
        fmt.Println(greeting)
}

func main() {
        sayHello("Good evening")
}
```
```:実行結果
Good evening
```
```:cal関数のサンプルコード(引数あり。引数6を渡す。)
package main

import "fmt"

func cal(x int) {
        fmt.Println(x * 3)
}

func main() {
        cal(6)
}
```
```:実行結果
18
```
```:cal関数のサンプルコード(複数の引数を渡す。引数6と3を渡す。)
package main

import "fmt"

func cal(x int, y int) {
        fmt.Println(x / y)
}

func main() {
        cal(6, 3)
}
```
```:実行結果
2
```
```:cal関数のサンプルコード(引数のデータ型省略。複数の引数を渡す。引数6と3を渡す。)
package main

import "fmt"

func cal(x, y int) {
        fmt.Println(x / y)
}

func main() {
        cal(6, 3)
}
```
・同じデータ型の場合、上記のように省略することができる

```:実行結果
2
```

```:cal関数のサンプルコード(戻り値がある場合)
package main

import "fmt"

func cal(x, y int) int {
        return (x / y)
}

func main() {
        result := cal(6, 3)
        fmt.Println(result)
}
```
```:実行結果
2
```

```:cal関数のサンプルコード(戻り値が複数ある場合)
package main

import "fmt"

func cal(x, y int) (int, int) {
        return (x / y), (x * y)
}

func main() {
        result01, result02 := cal(6, 3)
        fmt.Println(result01, result02)
}
```
```:実行結果
2 18
```
```:cal関数のサンプルコード(複数の戻り値を変数に格納して返す)
package main

import "fmt"

func cal(x, y int) (int, int) {
        a := x / y
        b := x * y

        return a, b
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}
```
```:実行結果
2 50
```
```:cal関数のサンプルコード(複数の戻り値を変数に格納して返す。変数は関数の{}外で宣言。)
package main

import "fmt"

func cal(x, y int) (a int,b int) {
        a = x / y
        b = x * y

        return a, b
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}
```
・関数の戻り値は、cal関数の波括弧の外で宣言することができる
・そのため、宣言と同時に代入する「:=」ではなく、単純に「=」だけでよくなる

```:実行結果
2 50
```
```:cal関数のサンプルコード(複数の戻り値を変数に格納して返す。変数は関数の{}外で宣言。returnのあとの変数の省略。)
package main

import "fmt"

func cal(x, y int) (a int,b int) {
        a = x / y
        b = x * y

        return
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}
```
・関数の戻り値は、cal関数の波括弧の外で宣言しているため、returnのあとの変数の記述も省略できる

```:実行結果
2 50
```

### 関数式
・関数を変数に代入することができる

```:関数式のサンプルコード
package main
import "fmt"

func main() {
    hello := func (greeting string) {
        fmt.Println(greeting)
    }

    hello("Good morning")
}
```
・helloという変数に関数を代入できる
・funcのあとの関数名は省略できる
・その後の記述は、通常の関数の定義方法と同じ
・実行方法は、関数のあとに丸括弧
・丸括弧の中に引数を記述
・funcのあとに関数名がない関数を無名関数という

```:実行結果
Good morning
```

```:関数式のサンプルコード
package main
import "fmt"

func main() {
    func (greeting string) {
        fmt.Println(greeting)
    }("Good morning")
}
```
・無名関数は、そのまま引数を渡して実行することができる
・無名関数のあとに、すぐに丸括弧で引数を与える

```:実行結果
Good morning
```
### init()
・特殊な関数で、一番はじめ(mainより先)に実行される関数

```:init関数のサンプルコード
package main
import "fmt"
func init() {
	fmt.Println("init()はmain()より先に実行する")
}
func main() {
	fmt.Println("Hello world!")
}
```
```:実行結果
init()はmain()より先に実行する
Hello world!
```
# ポインタ
### Go言語のポインタとは
・変数が存在するメモリ上の場所を「アドレス」といい、そのアドレスを格納可能な変数を「ポインタ」と呼ぶ
・例えば、「int型」変数のアドレスを格納できるポインタの型は、「* int」型というように、型の前に「* 」を付ける
・変数からアドレスを取得するときは「&(アドレス演算子)」を使う
・反対にアドレスが指し示す変数にアクセスするときは「*(間接参照演算子)」を使う

```:ポインタのサンプルコード
package main

import 	"fmt"

func main() {

	// int型のポインタ変数を宣言
	var ptr *int

	// int型の変数を宣言
	var i int = 12345

	// アドレス演算子を使い、iのアドレスをptrに代入
	ptr = &i
	
	//出力
	fmt.Println("iのアドレス", &i)
	fmt.Println("ptrの値(変数iのアドレス)", &i)

	fmt.Println("iの値", i)
	fmt.Println("ポインタ経由のi値", *ptr)

	// ポインタ経由でiの値を変更
	*ptr = 999

	//出力
	fmt.Println("ポインタ経由で変更したiの値", i)

}
```
```:実行結果
iのアドレス 0xc000018050
ptrの値(変数iのアドレス) 0xc000018050
iの値 12345
ポインタ経由のi値 12345
ポインタ経由で変更したiの値 999
```

### ポインタ渡しと値渡し
・ある変数を関数に渡すと実際の値のコピーが渡されるので、呼び出された関数内で値を変更しても関数の呼び出し元には一切、影響しない
・一方で、値のポインタを関数に渡した時は、値の実体(ポインタの指し示す値)は関数の呼び出し元も同じであるため、呼び出した関数内で呼び出し元の値を変更することができる
・このように、ポインタを使って値を渡すことを一般的に「ポインタ渡し」と呼ぶ
・反対に値のコピーを受け渡すことを「値渡し」と呼ぶ

```:ポインタ渡しと値渡しのサンプルコード
package main

import 	"fmt"

func main() {

	// int型の変数を２つ宣言
	a, b := 1, 1

	// 関数に変数を渡す
	// aは値をそのまま渡す。値渡し。
	// bはアドレス演算子を使ってポインタとして渡す。ポインタ渡し。
	double(a, &b)

	//出力
	fmt.Println("値渡し", a)
	fmt.Println("ポインタ渡し", b)
}

// この関数のパラメータxは値のコピーを受け取り、
// yはポインタ(正確にはポインタのコピー)を受け取る
func double(x int, y *int) {

	// 変数の値を変更
	x = x * 2

//間接参照演算子を使用し、ポインタyが指し示す変数の値を変更
	*y = *y * 2
	
}
```
```:実行結果
値渡し 1
ポインタ渡し 2
```

# 構造体
### 構造体とは
・異なるデータ型の変数を1つにまとめたもの
・構造体を作ることを「構造体を定義する」という

### フィールド
・構造体の中に定義した変数のことをフィールドという
・構造体にフィールドを追加することを「フィールドを定義する」という
・フィールドは、変数と同じように、数値や文字列を代入したり、参照したりすることができる

### 構造体の定義方法

```:構造体の定義方法
package main

import "fmt"

type Student struct {
}

func main() {        
}
```
### フィールドを定義

```:フィールドの定義サンプルコード
package main

import "fmt"

type Student struct {
        name string
        math float64
        english float64
}

func main() {        
}
```

```:フィールドの定義サンプルコード
package main

import "fmt"

type Student struct {
        name string
        math,english float64
}

func main() {        
}
```
・上記のようにフィールドは変数と同じように、カンマで区切って一括して定義することができる

### 構造体の使い方

```:構造体の使い方サンプルコード
package main

import "fmt"

type Student struct {
        name string
        math,english float64
}

func main() {
        var s Student
        s.name = "sato"
        s.math = 80
        s.english = 70

        fmt.Println(s)
}
```
・構造体も変数と同じで、予約語のvarを書いて、次に構造体を代入する変数を記載する
・上記の場合、変数名は「s」で、変数のあとに構造体名を記載する
・このように構造体を使えるようにすることを「構造体の初期化する」という

```:実行結果
{sato 80 70}
```
```:もう一つの構造体の初期化方法のサンプルコード
package main

import "fmt"

type Student struct {
        name string
        math,english float64
}

func main() {
        s := Student{"sato", 80, 70}
        fmt.Println(s)
}
```
・上記の記述はフィールドの上からの順番通りに値を代入しなければエラーになる

```:実行結果
{sato 80 70}
```
```:もう一つの構造体の初期化方法のサンプルコード(フィールド名指定)
package main

import "fmt"

type Student struct {
        name string
        math,english float64
}

func main() {
        s := Student{english: 70, math: 80, name: "sato"}
        fmt.Println(s)
}
```
・順番を入れ替えたい、一部のフィールドにのみ値を代入するには、フィールド名を指定して代入する方法を使えばよい

```:実行結果
{sato 80 70}
```

# メソッド
### メソッドとは
・構造体などの特定の型に関連づけられた関数のこと

### メソッドの定義方法

```:メソッドを使用したサンプルコード
package main

import "fmt"

type Student struct {
        name          string
        math, english float64
}

func (s Student) avg() {
        fmt.Println(s.name, (s.math+s.english)/2)
}

func main() {
        a001 := Student{"sato", 80, 70}
        a001.avg()
}
```
・構造体Studentを定義する
・avgメソッドを定義する
・funcとメソッドの間に丸括弧。丸括弧の中に、変数名、半角スペース、関連づける構造体名と記述することで、メソッドの中で、フィールドの値を使うなどができるようになる（この部分をレシーバと呼ぶ）
・a001に構造体を初期化をして代入する
・メソッドの使い方は、構造体を代入した変数(a001)、ドット、メソッド名

```:実行結果
sato 75
```
```:メソッドを使用したサンプルコード(メソッドに引数を渡す)
package main

import "fmt"

type Student struct {
        name string
}

func (s Student) avg(math, english float64) {
        fmt.Println((math + english) / 2)
}

func main() {
        a001 := Student{"sato"}
        a001.avg(80, 70)
}
```
・avgのあとの丸括弧に、渡す引数を記述する

```:実行結果
75
```
```:メソッドを使用したサンプルコード(メソッドに引数を渡す。戻り値がある場合。)
package main

import "fmt"

type Student struct {
        name string
}

func (s Student) avg(math, english float64) (avgResult float64) {
        avgResult = (math + english) / 2
        return
}

func main() {
        a001 := Student{"sato"}
        fmt.Println(a001.avg(80, 70))
}
```
・avgのあとの丸括弧に、渡す引数を記述する

```:実行結果
75
```
# 終わりに
貴重なお時間を使って最後まで読んで下さり、誠にありがとうございます！！
enjoy golang！！

-------
この記事は以下の情報を参考にしてします。
https://kino-code.com/category/super-introductory-course-golang/