恥知らずのウェブエンジニア -web engineer, shameless

これは一歩を踏み出すことができない者たちのブログ

PHPerが始めるgo言語入門 〜言語仕様〜

続いてgo言語の言語仕様を確認していきます。
五月雨でアレですが。

コメントアウト

1行
//

複数行
/*

*/

行末のセミコロン

ステートメント最後のセミコロンは省力可能。コンパイラが適切に挿入してくれる

インポート

import (
	"fmt"
	"strings"
)

import (
    f "fmt" //fという別名を使う
    _ "os" // _は対象パッケージを使わないことをコンパイラに明示する。使っていないパッケージがあるとコンパイルエラーになる
    . "strings" // .でパッケージ名を省略できる
)

変数の宣言

var 変数名 型 = 値
var message string = "hellow world"

複数同時に宣言

var hoge, foo, bar string = "hoge", "foo", "bar"

var (
	a string = "a"
	b		 = "b"
	c		 = "c"
)
同じ型なら2つ目以降は省力可能

関数内部での変数宣言

:=で型推論で宣言できる

func main() {
	// 同じ意味
	// var message string = "hello world"
	message := "hello world"
	fmt.Println(message)
}

定数

constで定数に
const Message string = "hello world"

初期値なしで宣言

var i int // i = 0
int => 0
float => 0.0
bool => false
string => ""
配列 => 要素0の配列
構造体 => プロパティが0の構造体
その他 nil

if文

if hoge > foo {
	
} else if hoge < foo {
	
} else {
	
}

3項演算子はなし
if1行だけもなし

ループ

ループはforだけ

for i := 0; i < 10; i++ {
	
}

いわゆるwhile的なfor
i := 0
for i < 10 {
	fmt.Printf("i = %d\n", i)
	i++
}

break,continue

i := 0
for {
	i++
	if i > 10 {
		break //ループ抜ける
	}

	if i % 2 == 0 {
		continue //偶数なら次のループへ
	}
	fmt.Println(n)
}

switch文

switch i {
	case 1:
		fmt.Println("1")
	case 2, 4:
		fmt.Println("2 or 4")
	case 5 < i:
		fmt.Println("greater 5")
	default
		fmt.Println("default")
}

switchで比較もオッケー
phpだとcaseに入ってもbreakを書かないと次のcaseへ進むが、golangは1つcaseが実行されたら、switchを抜ける
逆に1つcaseを実行されても次のcaseに行きたい時は[fallthrough]と書く

switch i {
	case 1:
		fmt.Println("1")
		fallthrough
	case 2, 4:
		fmt.Println("2 or 4")
		fallthrough
	default
		fmt.Println("default")
}

関数

func 関数名(引数 型) 戻り値の型 {
	
}


func sum(i, j int) { //sum(i int, j int)
	fmt.Println(i + j)
}


func sum(i, j int) int { //sum(i int, j int)
	return i + j
}
func main() {
	n := sum(1, 2)
	fmt.Println(n) //3
}


func change(i, j int) (int, int) {
	return j, i
}
func main() {
	x, y := 3, 4
	x, y = change(x, y)
	fmt.Println(x, y) //4 3
}

名前付きの戻り値

func div(i, j int) (result int, err error) {
	if j == 0 {
		err = errors.New("divied by zero")
		return // return 0, errと同じ
	}
		result = i / j
		return // return result, nilと同じ
}

無名関数

func main() {
	func(i, j int) {
		fmt.Println(i + j)
	}(2, 4)
}

配列

goの配列は固定長
var arr1 [4]string //4つの要素がある配列
arr[0] = "a"
arr[1] = "b"
arr[2] = "c"
arr[3] = "d"
fmt.Println(arr[0]) // a

// 宣言と同時に初期化
// どちらも同じ
arr := [4]string{"a", "b", "c", "d"}
arr := [...]string{"a", "b", "c", "d"}

関数に配列渡す時は値渡し

スライス

可変長の配列
var s []string

s := []string{"a", "b", "c", "d"}
fmt.Println(s[0]) // "a"

値追加
var s []string
s = append(s, "a") // 追加した結果を返す
s = append(s, "b")
s = append(s, "c", "d")
fmt.Println(s) // [a b c d]

s1 := []string{"a", "b"}
s2 := []string{"c", "d"}
s1 = append(s1, s2...) // s1にs2を追加
fmt.Println(s1) // [a b c d]

range

先頭から順番に処理
いわゆるforeach的な感じ

arr := [...]string{"a", "b", "c", "d"}

for i, s := range arr {
	// i = 添字, s = 値
	fmt.Println(i, s)
}

値の切り出し

s := []int{0, 1, 2, 3, 4, 5}
fmt.Println(s[2:4]) // [2 3]
fmt.Println(s[0:len(s)]) // [0 1 2 3 4 5]
fmt.Println(s[:3]) // [0 1 2 3]
fmt.Println(s[3:]) // [3 4 5]
fmt.Println(s[:]) // [0 1 2 3 4 5]

可変長引数

phpでもこういうのできるようになりますね
可変長で引数を取ることができる
func sum(nums ...int) (result int) {
	// numsは[]int型
	for _, n := range nums { //添字は捨てる
		result += n
	}
	return
}

func main() {
	fmt.Println(sum(1, 2, 3, 4)) // 10
}

マップ

ハッシュ的なやつです
キーと値で、格納

var month map[int]string = map[int]string{}

month[1] = "January"
month[2] = "February"
fmt.Println(month) // map[1:January 2:February]

month := map[int]string{
	1: "January",
	2: "February",
}
fmt.Println(month) // map[1:January 2:February]


値の取得
jan := month[1]
fmt.Println(jan) // January

2つ目の戻り値に値があるかboolで返してくれる
_, ok := month[1]
if ok {
	// データがあった場合
}

マップから情報を消すのはdelete

delete(month, 1)
fmt.Println(month) // map[2:February]

かなり雑でアレですが。。。



感謝致します。
f:id:ogataka50:20150421003559j:plain