3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go初心者のためのメモ(超基本編)

Last updated at Posted at 2019-07-09

Go言語とは

なんだか並列処理とかが簡単に実装できるという噂。
正直、まだよくわかりません!
公式のチュートリアルをやっていき、引っかかるところを自分のメモがてら、つらつら書いていきます。

基本的な定義の記述

パッケージの定義

C++でいうヘッダーをGoではパッケージと呼ぶ。
書き方は以下のように、それぞれのファイルの最初に記述する。
他パッケージの読み込みはimportの中で行う。

main.go
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	// 他パッケージを読み込む際は最後のパッケージ名だけでよい
	// この場合は"math/rand"ではなく"rand"だけでオッケー。
	fmt.Println("My favorite number is", rand.Intn(10))
}

C++でいうmain文はgoでいうmainパッケージにあたり、プログラムはmainパッケージから実行される。

関数の定義

他の言語と異なり、引数は変数名の後ろに記述する。
同じ型の変数が続く場合は省略もできる。例えば、x int, y intx, y intのように。

main.go
package main

import "fmt"

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

func main() {
	// sum = add(1, 4)だと"undefined: sum"ってエラーを吐く
	// ちゃんと書くならvar sum = add(1, 4)
	sum := add(1, 4)
	fmt.Println(sum)
}

また、戻り値を最初に宣言して処理を行う書き方もある。
このとき、returnにはなにも書かない。

main.go
package main

import "fmt"

func add_each(input int) (output1, output2 int) {
	output1 = input + 1
	output2 = input + 2
	return
}

func main() {
	fmt.Println(add_each(17))
}
// 18, 19を出力

関数の引数を関数にする(ちょい応用)

自分はすぐに理解できなかったので別項目として記載します。
go言語では関数の引数に関数を入れることができる。

main.go
package main

import (
	"fmt"
)

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	plus := func(x, y float64) float64 {
		fmt.Println("x:", x, ",y:", y)
		return x + y
	}
	fmt.Println(plus(5, 12))
	fmt.Println("==========")
	compute(plus)
	fmt.Println("==========")
	fmt.Println(compute(plus))
}
/* 実行結果
x: 5 ,y: 12
17
==========
x: 3 ,y: 4
==========
x: 3 ,y: 4
7
*/

慣れてないとよく分からないんですが
func compute(fn func(float64, float64) float64) float64{return fn(3, 4)}が、

float64の引数が2つの関数だったら、どんな関数でも実行できるようなcomputeっていう関数を定義

と脳内変換すれば理解できるんですかね?
自分はそう考えています。

変数の定義

変数の定義はvarと記述することで定義できる。
省略の記述が多いので以下にまとめる。

  • 初期値を代入する場合、型の宣言を省略できる。
  • 関数の中であれば:=演算子でvar宣言を省略できる。
  • 初期値を省略した場合、型に応じて0""false等が代入される。
main.go
package main

import "fmt"

var i, j int = 1, 2
var c, python, java = true, false, "no!"

func main() {
	k := 3
	var zero int
	fmt.Println(i, j, k, c, python, java, zero)
}
// 1 2 3 true false no! 0 を出力

定数の定義

constで宣言できる。
:=演算子は使うことができない。

基本的な変数に対する処理

変数の型変換

型変換は型名()だけで行うことができる。

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

// よりシンプルな記述
i := 42
f := float64(i)
u := uint(f)

型の確認

fmtPrintf関数による方法をここでは紹介する。
cのprintf関数と似ていて%なにかで変数を文字列に埋め込んで出力することができる。
変数の型は%T、変数の値は全て%vで表せる。

var f float64 = 1
fmt.Printf("(%v, %T)\n", f, f) // (1, float64)を返す

Printfでは他にもクラスの中身の確認や関数の引数も調べることができる。
詳しくは、@rock619さんの記事にまとまっているのでそちらを参照。

「fmt.Printfなんかこわくない」
https://qiita.com/rock619/items/14eb2b32f189514b5c3c#x-3

イテレータや条件分岐

for文

for文の条件式の()が不要。
また初期化、後処理を省略することもできる。

main.go
package main

import "fmt"

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

	// 省略形(これはもうwhile文と一緒)
	n := 1
	for ; n < 1000; {
		n += n
	}
	fmt.Println(n)

	// さらに省略形
	m := 1
	for m < 1000 {
		m += m
	}
	fmt.Println(m)
}

go言語にwhile文等は存在せず、イテレータはfor文のみ。
無限ループはfor文の条件さえも省略してfor{}と記述する。

if文

for文と同じく()を省略して書く。

main.go
package main

import (
	"fmt"
	"math"
)

func sqrt(x float64) string {
	if x < 0 {
		return sqrt(-x) + "i"
	}
	return fmt.Sprint(math.Sqrt(x))
}

func main() {
	fmt.Println(sqrt(2), sqrt(-4))
}

また、for文と同じように初期値の代入を記述することも可能。

main.go
package main

import (
	"fmt"
)

func half(x int) bool {
	if x % 2 == 0 {
		return true
	} else {
		return false
	}
}

func main() {
	number := 5
	// vを初期値としてif文で評価
	if v:= half(number); v==true {
		fmt.Println("偶数")
	} else {
		fmt.Println("奇数")
	}		
}

swich文

上から下にcaseの値を評価していき、条件が一致すればbreakする。

main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("When's Saturday?")
	today := time.Now().Weekday()
	switch time.Saturday {
	case today + 0:
		fmt.Println("Today.")
	case today + 1:
		fmt.Println("Tomorrow.")
	case today + 2:
		fmt.Println("In two days.")
	default:
		fmt.Println("Too far away.")
	}
}

defer文(実行遅延を行うもの)

デストラクタのように処理の最後に実行させるためのもの。
例えば以下のコードの場合、helloが先に出力され、最後にworldが出力される。

main.go
package main

import "fmt"

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}

ポインタとか

ポインタ

Cのポインタと一緒。なにも初期値を与えないとnilを返す。
&演算子でポインタの示すアドレスを指定。
*演算子でポインタの指す値を取得。

var p *int // ポインタの定義

i := 42
p = &i
fmt.Println(*p) // 42を返す
fmt.Println(p) // アドレス0x414020を返す

構造体

これもCと似通っている。ドットでアクセスする。
ポインタからメンバ変数Xにアクセスするときは下記のように省略して書ける。

main.go
package main

import "fmt"

type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	fmt.Println(v) // {1 2}を出力
	v.X = 4
	fmt.Println(v.X) // 4を出力

	p : = &v
	p.X = 5 // (*p).Xと書かなくてよい
 	fmt.Println(v.X) // 5を出力
}
3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?