[box class="blue_box" title="☑本記事の内容"]
- ポインタ
- newとmakeの違い
- struct
[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]
[/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 }