Go言語(または Golang)は、Googleによって開発されたオープンソースのプログラミング言語です。シンプルで効率的、そして並行処理に強いという特徴があります。
Go言語の公式サイト(https://golang.org)からインストーラーをダウンロードし、指示に従ってインストールしてください。
まずは、定番の "Hello, World!" プログラムを作成しましょう。
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
このコードを hello.go
として保存し、ターミナルで以下のコマンドを実行します:
go run hello.go
Go言語での変数宣言と定数定義の方法を学びましょう。
var x int = 10
y := 20 // 型推論による短縮形
const Pi = 3.14159
Go言語の基本的なデータ型には以下があります:
Go言語の制御構造には、if文、for文、switch文などがあります。
// if文
if x > 0 {
fmt.Println("Positive")
} else if x < 0 {
fmt.Println("Negative")
} else {
fmt.Println("Zero")
}
// for文
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// switch文
switch day {
case "Monday":
fmt.Println("It's Monday")
case "Tuesday":
fmt.Println("It's Tuesday")
default:
fmt.Println("It's another day")
}
Go言語での関数定義と使用方法を見てみましょう。
func add(x int, y int) int {
return x + y
}
func main() {
result := add(5, 3)
fmt.Println("5 + 3 =", result)
}
Go言語ではパッケージを使ってコードを整理します。
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("The square root of 16 is", math.Sqrt(16))
}
Go言語では、配列は固定長、スライスは可変長のデータ構造です。
// 配列の宣言と初期化
var a [5]int
b := [3]int{1, 2, 3}
// 配列の要素にアクセス
fmt.Println(b[1]) // 出力: 2
// スライスの宣言と初期化
s := []int{1, 2, 3, 4, 5}
// スライスの追加
s = append(s, 6)
// スライスの一部を取り出す
fmt.Println(s[1:4]) // 出力: [2 3 4]
マップはキーと値のペアを格納するデータ構造です。
// マップの宣言と初期化
m := make(map[string]int)
// 要素の追加
m["apple"] = 1
m["banana"] = 2
// 要素の取得
value, exists := m["apple"]
if exists {
fmt.Println(value) // 出力: 1
}
// 要素の削除
delete(m, "banana")
// マップの反復処理
for key, value := range m {
fmt.Printf("%s: %d\n", key, value)
}
// マップのサイズ
fmt.Println(len(m))
Go言語では、エラーは値として扱われます。多くの関数は、最後の戻り値としてエラーを返します。
f, err := os.Open("filename.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// カスタムエラーの作成
type MyError struct {
message string
}
func (e *MyError) Error() string {
return e.message
}
func doSomething() error {
return &MyError{"something went wrong"}
}
Go言語では、os
パッケージとio/ioutil
パッケージを使用してファイルの読み書きを行います。
import (
"fmt"
"io/ioutil"
)
func readFile() {
content, err := ioutil.ReadFile("file.txt")
if err != nil {
fmt.Println("Error reading file:", err)
return
}
fmt.Println(string(content))
}
import (
"fmt"
"io/ioutil"
)
func writeFile() {
content := []byte("Hello, Go!")
err := ioutil.WriteFile("output.txt", content, 0644)
if err != nil {
fmt.Println("Error writing file:", err)
return
}
fmt.Println("File written successfully")
}
Go言語の強みの一つである並行処理について学びましょう。
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
この例では、go
キーワードを使用してゴルーチン(軽量スレッド)を起動しています。
チャネルは、ゴルーチン間でデータを送受信するための通信機構です。
// チャネルの作成
ch := make(chan int)
// データの送信
go func() {
ch <- 42
}()
// データの受信
value := <-ch
fmt.Println(value) // 出力: 42
// バッファ付きチャネル
bufCh := make(chan int, 2)
bufCh <- 1
bufCh <- 2
// bufCh <- 3 // これはブロックする(バッファが満杯)
// チャネルのクローズ
close(ch)
// rangeを使用したチャネルの読み取り
for v := range ch {
fmt.Println(v)
}
Go言語の標準ライブラリnet/http
を使用してシンプルなAPIを作成できます。
package main
import (
"encoding/json"
"log"
"net/http"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
http.HandleFunc("/api/person", handlePerson)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handlePerson(w http.ResponseWriter, r *http.Request) {
person := Person{Name: "John Doe", Age: 30}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(person)
}
go.modファイルは、プロジェクトの依存関係を管理するために使用されます。
// go.modファイルの作成
go mod init example.com/myproject
// go.modファイルの例
module example.com/myproject
go 1.16
require (
github.com/gin-gonic/gin v1.7.2
github.com/go-sql-driver/mysql v1.6.0
)
// 依存関係の追加
go get github.com/some/dependency
// 依存関係の更新
go get -u