Skip to content

Instantly share code, notes, and snippets.

@mtskf
Last active July 10, 2022 07:54
Show Gist options
  • Save mtskf/15382dd85bf53f4cf436997a5188f3e7 to your computer and use it in GitHub Desktop.
Save mtskf/15382dd85bf53f4cf436997a5188f3e7 to your computer and use it in GitHub Desktop.
[GoLang]

GoLang Basics

Setup

Hello World

$ cd ~/go/
$ mkdir src && cd src
$ touch hello.go
package main
import "fmt"

func main () {
    fmt.Println("HelloWorld!! Golang!!!")
}
$ go mod init hello  # gomodを追加
$ go run hello.go    # hello.goを実行

$ go build hello.go  # 実行ファイルを作成
$ ./hello            # 実行ファイルを実行

Import Packages

複数同時にインポートしたり、aliasを設定したりできる

import (
  p1 "package1"
  "package2"
)

Docを参照する

$ go doc time.Now

Variables & Constants

const msg = "Hello world!"
const pi = 3.142865

var stationName string
var nextTrainTime int8
var isUptownTrain bool
var flavorScale float32
  • int8, int16, int32, int64 -> 整数
  • uint8, uint16, uint32, uint64 -> 自然数
  • 数値変数の初期値は0
  • stringの初期値は空文字列 ""
  • int, uint, float とすると、環境に応じて32bitと64bitを切り替えてくれる

初期値を指定してtype inferする

var nuclearMeltdownOccurring = true
var radiumInGroundWater = 4.521
var daysSinceLastWorkplaceCatastrophe = 0
var externalMessage = "Everything is normal. Keep calm and carry on."

さらに:=を使うことでvarも省略可能

nuclearMeltdownOccurring := true
radiumInGroundWater := 4.521
daysSinceLastWorkplaceCatastrophe := 0
externalMessage := "Everything is normal. Keep calm and carry on."

複数同時に変数を宣言・定義したり…

var part1, part2 string
part1 = "To be..."
part2 = "Not to be..."

quote, fact := "Bears, Beets, Battlestar Galactica", true

fmt

fmt.Println("Is", guess, "your final answer?") // スペース区切り+改行
fmt.Print("Is", guess, "your final answer?") // スペース区切りなし、改行なし

fmt.Printf("Are you a %v or a %v person?", animal1, animal2) // %vで値を出力
fmt.Printf("This value's type is %T.", specialNum) // %Tで型を出力
fmt.Printf("You must be %d years old to vote.", votingAge) // %dで整数を出力
fmt.Printf("You're averaging: %f.", gpa) // %fで小数を出力
fmt.Printf("You're averaging: %.2f.", gpa) // %.2fで小数点以下2桁まで出力

Sprint, Sprintln, Sprintf でフォーマットしてからPrintで出力

template := "I wish I had a %v."
pet := "puppy"
wish := fmt.Sprintf(template, pet)
fmt.Println(wish)

ユーザーからの出力を受け取る

var response string
fmt.Scan(&response)

フォーマットスキャン

Sscanf(" 1234567 ", "%5s%d", &s, &i) // s: "12345", i: 67

乱数の生成

package main
import (
  "fmt"
  "math/rand"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())  // seedを設定
  fmt.Println(rand.Intn(100))  // 0-99
}

関数

func multiplier(x, y int32) int32 {
  return x * y
}

// 複数の返り値
func hoge() (string, int) {
  return "hoge", 1
}
hoo, faa := hoge()

// 遅延実行 -> defer付けると、一番最後に実行される
defer disconnectDatabase()

ポインター

message := "Hello world!"
address := &message    // var address *string
fmt.Println(address)   // Address 0x414020
fmt.Println(*address)  // "Hello world!"
*address = "Hello Go!" // messageが書き換えられる
fmt.Println(message)   // "Hello Go!"

scope外の変数を参照するには、ポインターを使う

func addHundred (numPtr *int) {
  *numPtr += 100
}

func main() {
  x := 1
  addHundred(&x)
  fmt.Println(x) // Prints 101
}

ループ

i := 0

// while loop っぽいやつ (indefinite loop)
for i < 10 {
  i++
}

// array をイタレート
letters := []string{"A", "B", "C", "D"}
for index, value := range letters {
  fmt.Println("Index:", index, "Value:", value)
}

// map をイタレート
book := map[string]string{
  "John": "12 Main St",
  "Janet": "56 Pleasant St",
  "Jordan": "88 Liberty Ln",
}
for name, address := range book {
  fmt.Println("Name:", name, "Address:", address)
}

Array & Slices

// Arrays (fixed length)
var playerNames [5]string
trianbleSides := [3]int{15, 26, 30} // 宣言と初期化を同時にする
triangleAngles := [...]int{30, 60, 90} // 配列長を自動でセット
len(playerNames) // length of array, 5

// Slices
var numberSlice []int
books := []string{}
len(books) // current length of slice
cap(books) // current max cap of slice
books.append(books, "Lorem Ipsum") // append to slice
// 注意:Sliceの要素を変更すると、元のArrayも変更される

// Slice of Array
array := [5]int{2, 5, 7, 1, 3}
sliceVersion := array[:] // slice of whole array [2 5 7 1 3]
partialSlice := array[2:5] // partial slice [7 1 3]

配列の引数に使うときの注意点。ArrayとSliceで異なるよ。

// funcにArrayを渡すときはPassed by value
func hoge(foo [4]int) {
  ...
}
// funcにSliceを渡すとPassed by reference
// func内で変更すると、元のArray/Sliceも変更される
func hoge(faa []int){
  ...
}

Map

prices := make(map[string]float32) // create empty map
prices := map[string]float32 // create without using make (map literal)

contacts := map[string]int{  // create & initialise map
  "Joe":    2126778723,
  "Angela": 4089978763,
  "Shawn":  3143776876,
  "Terell": 5026754531,
}

customer := contacts["Joe"] // accessing map value
customer,status := customers["billy"] // if key not found, status is false

contacts["Mitsuki"] = 123456789 // add new key-value pair
delete(contacts, "Mitsuki") // delete item

Struct

type Pet struct {
	name    string
	petType string
	age     int
}

func main() {
	nuggets := Pet{"Nuggets", "dog", 4}
	mittens := Pet{"Mittens", "cat", 7}
  mogan := Pet{
    name: "Mogan",
    petType: "fish",
  } // ageがわからないときは、field名を指定してインスタンス作成
}

Method

type Rectangle struct {
  length float32
  width float32
}

func (rectangle Rectangle) area() float32{
  return rectangle.length * rectangle.height
}

// methodからfieldを変更するには、ポインターを使う
func (rectangle *Rectangle) modify(newLength float32){
  rectangle.length = newLength
}

func main() {
  rectangle := Rectangle{10, 5}
  fmt.Println(rectangle.area())
  rectangle.modify(20)
}

Nested Struct

type Point struct {
	x int
	y int
}

type Circle struct {
  Point // anonymous field
  radius int
}

func main() {
	circle := Circle{Point{4,5}, 2}
  fmt.Println(circle.x)
}
  • point Point ではなく Anonymous field にすることで、circle.xとできる。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment