Go 入門

Go言語入門⑩ ~ポインタ・newとmakeの違い・struct~

[box class="blue_box" title="☑本記事の内容"]

  • ポインタ
  • newとmakeの違い
  • struct

[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]

  1. ポインタ
  2. newとmakeの違い
  3. struct

[/box]

ポインタ

[box class="yellow_box" title="✔ポインタの目次"]

[/box]

基本的なこと

[box class="glay_box"]

  • 出力の際に&をつけることでアドレスの表示が出来る
  • 宣言の際にアドレス表記にするときはアスタリスク(*)をつける

[/box]

package main

import "fmt"

func main() {
	var n int = 100
	fmt.Println(n)

	fmt.Println(&n)

	var p *int = &n

	fmt.Println(p)

	fmt.Println(*p)
}
(結果)
100
0xc000012090
0xc000012090
100

値の書き換え

[box class="glay_box"]

  • ポインタを使用すると通常書き変わらない値が書き変わってしまう
  • 実際に自分で色々試してみるのがおすすめ
  • 下記で実行すると通常書き変わらない

[/box]

package main

import "fmt"

func one(x int) {
	x = 1
}

func main() {
	var n int = 100
	one(n)
	fmt.Println(n)
}
(結果)
100

[box class="glay_box"]

  • ポインタを使用すると値が書き変わる

[/box]

package main

import "fmt"

func one(x *int) {
	*x = 1
}

func main() {
	var n int = 100
	one(&n)
	fmt.Println(n)
}
(結果)
1

newとmakeの違い

[box class="yellow_box" title="✔newとmakeの違いの目次"]

[/box]

ポインタの宣言

[box class="glay_box"]

  • ポインタを空の状態で宣言する場合はnewを使用する
  • newを使用しなかった場合はnilとなってしまう

[/box]

package main

import "fmt"

func main() {
	var p *int = new(int)
	fmt.Println(p)

	var p2 *int
	fmt.Println(p2)
}
(結果)
0xc000012090
nil

[box class="glay_box"]

  • newで宣言したほうはその後も値を足せるがしてない場合はエラーとなる

[/box]

package main

import "fmt"

func main() {
	var p *int = new(int)
	fmt.Println(*p)
	*p++
	fmt.Println(*p)
}
(結果)
0
1
package main

import "fmt"

func main() {
	var p2 *int
	fmt.Println(p2)
	*p2++
	fmt.Println(p2)
}
(結果)エラー表示
nil
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x9a581f]

newとmakeの違い

[box class="glay_box"]

  • newはポインタを宣言する時に使用するもの
  • makeはスライスなどを宣言する時に使用するもの

[/box]

package main

import "fmt"

func main() {
	s := make([]int, 0)
	fmt.Printf("%T\n", s)

	m := make(map[string]int)
	fmt.Printf("%T\n", m)

	ch := make(chan int)
	fmt.Printf("%T\n", ch)

	var p *int = new(int)
	fmt.Printf("%T\n", p)

	var st = new(struct{})
	fmt.Printf("%T\n", st)
}
(結果)
[]int
map[string]int
chan int
*int
*struct {}

struct

[box class="yellow_box" title="✔structの目次"]

[/box]

基本的なこと

[box class="glay_box"]

  • structは構造体の事
  • よく利用される
  • 値を入れない場合は初期値が自動で入る

[/box]

package main

import "fmt"

type Vertex struct {
	X, Y int
	S    string
}

func main() {
	v := Vertex{X: 1, Y: 2}
	fmt.Println(v)
	fmt.Println(v.X, v.Y)
	v.X = 100
	fmt.Println(v.X, v.Y)

	v2 := Vertex{X: 1}
	fmt.Println(v2)

	v3 := Vertex{1, 2, "test"}
	fmt.Println(v3)

	v4 := Vertex{}
	fmt.Println(v4)
}
(結果)
{1 2 }
1 2
100 2
{1 0 }
{1 2 test}
{0 0 }

アドバンス

[box class="glay_box"]

  • 宣言の仕方は違っても同じ結果となる宣言方法がある
  • structの場合、ポインタはnewよりも&がよく使われる

[/box]

package main

import "fmt"

type Vertex struct {
	X, Y int
	S    string
}

func main() {
	v4 := Vertex{}
	fmt.Printf("%T %v\n", v4, v4)

	var v5 Vertex
	fmt.Printf("%T %v\n", v5, v5)

	v6 := new(Vertex)
	fmt.Printf("%T %v\n", v6, v6)

	v7 := &Vertex{}
	fmt.Printf("%T %v\n", v7, v7)
}
(結果)
main.Vertex {0 0 }
main.Vertex {0 0 }
*main.Vertex &{0 0 }
*main.Vertex &{0 0 }

Go言語入門⑪へ ≫

≪ Go言語入門⑨へ

目次

-Go, 入門