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

☑本記事の内容
  • ポインタ
  • newとmakeの違い
  • struct
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発

ポインタ

✔ポインタの目次

基本的なこと

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

値の書き換え

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

import "fmt"

func one(x int) {
	x = 1
}

func main() {
	var n int = 100
	one(n)
	fmt.Println(n)
}
(結果)
100
  • ポインタを使用すると値が書き変わる
package main

import "fmt"

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

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

newとmakeの違い

✔newとmakeの違いの目次

ポインタの宣言

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

import "fmt"

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

	var p2 *int
	fmt.Println(p2)
}
(結果)
0xc000012090
nil
  • newで宣言したほうはその後も値を足せるがしてない場合はエラーとなる
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の違い

  • newはポインタを宣言する時に使用するもの
  • makeはスライスなどを宣言する時に使用するもの
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

基本的なこと

  • structは構造体の事
  • よく利用される
  • 値を入れない場合は初期値が自動で入る
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 }

アドバンス

  • 宣言の仕方は違っても同じ結果となる宣言方法がある
  • structの場合、ポインタはnewよりも&がよく使われる
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言語入門⑨へ

目次

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です