Closed10

golang再入門

iwamasaiwamasa

初めに

2022年にGo言語で業務をしていたのですが、暫く離れてしまってブランクがあるので再入門した際のメモです。

いい感じにまとまったら後で記事にするかも。

他のユーザーの投稿を許可しておくので、もしも今はこれがデファクトだよ〜みたいなご指摘があればコメント頂けますと幸いです。

iwamasaiwamasa

今回のゴール

  • Go言語を使用してWebアプリケーションの開発ができるようになる
    • 開発環境(特にパッケージ管理まわり)を復習する
    • 基本構文からやり直す

具体的にやること

  • 開発環境・パッケージ管理について学ぶ
  • 基本構文を A Tour of Go で学ぶ
  • Webアプリケーション開発に必要なパッケージを調査し、実際にTODOアプリを構築する
iwamasaiwamasa

基本構文の復習

変数

A Tour of Go から拝借

基本データ型

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32
     // represents a Unicode code point

float32 float64

complex64 complex128

変数定義

// varで明示的に宣言する
var i int
i = 1

// 暗黙的に宣言する(関数の中でのみ宣言可能)
i := 1

// まとめて
var (
    a int
    b int
    c string
)

定数

const で定義する。省略形は存在しない

const TEST = "TEST"

関数

func で宣言する

func hoge() {
    fmt.Println("hoge!!")
}

// 引数
func add(x int, y int) int {
	return x + y
}

// 引数(省略形)
func add(x, y int) int {
	return x + y
}

// 複数return
func swap(x, y string) (string, string) {
	return y, x
}

// 名前付きreturn
func named(a, b string) (x, y string) {
	x = "x: " + a
	y = "y: " + b
	return
}
iwamasaiwamasa

基本構文の復習 Part 2

For

for i := 0; i < 10; i++ {
	fmt.Println(i)
}

// whileみたいな書き方
for ; sum < 1000; {
	sum += sum
}

// これでもOK
for sum < 1000 {
	sum += sum
}

// 条件を設定しないと無限ループ(内部でbreakすれば抜けられる)
for {
}

If

if a < 100 {
    fmt.Println("a is less than 100")
}

// その場で変数宣言も可能
if i := 100; i < 100 {
	fmt.Println("i is less than 100")
} else if i == 100 {
	fmt.Println("i equal 100")
} else {
	fmt.Println("i is more than 100")
}

Switch

break を設定しなくても一致した時点でbreakする

str := "ccc"
switch str {
    case "aaa":
        fmt.Println("str is aaa")
    case "bbb":
        fmt.Println("str is bbb")
    case "ccc":
        fmt.Println("str is ccc")
    default:
        fmt.Println("undefined pattern")
}

Defer

関数が戻るまで遅延させる

func main() {
	// 最後のhelloが出力されてから実行される
	defer fmt.Println("world")

	fmt.Println("hello")
}

deferは LIFO(last in first out) なので、最後に実行されたものから順番に出力される

func main() {
	// 9 ,8, 7, 6...と出力される
	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}
}
iwamasaiwamasa

ポインタ

ポインタは値のメモリアドレスを指します。

概念はC言語と同様でメモリアドレスの位置を示す

// 宣言
var p *int

// 以下の場合、pはiのアドレスを示す
i := 42
p = &i

// ポインタを通して元の変数の値を取り出す
fmt.Println(*p)

// 値に対して再代入も可能(iの内容が書き変わる)
*p = 1
fmt.Println(i) // 1になる

実際にどんな時にポインタを使うのか?
個人的な理解だとポインタを関数に渡し、参照元の変数を書き換えたい時に使う(参照渡し)

iwamasaiwamasa

構造体

type Vertex struct {
	X, Y float64
}

// クラスみたいにメソッドを生やすことができる
func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

// ポインタレシーバで宣言
// こうすることでプロパティの内容を書き換えできる
func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func main() {
	v := Vertex{3, 4}
	fmt.Println(v.X)
	fmt.Println(v.Abs())
	
	v.Scale(10)
	fmt.Println(v.X, v.Y)
}
iwamasaiwamasa

配列

// 宣言
var a [2]string
// 代入
a[0] = "a"
a[1] = "b"

// 一括代入
numbers := [3]int{1, 2, 3}

// スライス
var s []int = numbers[1:2] // 2, 3だけ取れる

// rangeを利用することでforeachみたいなことができる
for i, n := range numbers {
    fmt.Println(i, n)
}
このスクラップは3ヶ月前にクローズされました