LoginSignup
5
2

More than 5 years have passed since last update.

railsしかやって来なかった人のGoの基礎文法まとめ

Last updated at Posted at 2019-01-09

はじめに、、、

プログラミングをはじめて10ヶ月間railsしかやってこなかったのですが、、、  
Goを実務で使うことになり大まかにですが基礎文法を軽く1周したのでそのまとめをしたいと思います。  

Hello World

import "fmt"

func main() {
  fmt.Println("Hello World")
}

//〜出力〜
//Hello World

golangは出力は基本的に fmt.Println を使うそうです。  
またそのために "fmt"をimportしなければいけません

関数(func) ※Rubyだとdef

引数なし

import "fmt"

func hello() {
  fmt.Println("Hello World")
}

func main() {
  hello()
}

//〜出力〜
//Hello World

引数有り

import "fmt"

func square(x int, y int) {
  fmt.Println(x*y)
}

func main() {
  square(5, 10)
}

//〜出力〜
//50

引数の型名を宣言する必要がある。
また上のように引数の型が同じ場合下のようにも書ける

func square(x, y int) {
  fmt.Println(x*y)
}

返り値あり

import "fmt"

func hello() string{
  return "Hello world"
}

func main() {
  fmt.Println(hello())
}

//〜出力〜
//Hello World

返り値を返す場合は func 関数名() 返す値の型 というように書く必要がある

jsの即時関数的な感じ

import "fmt"

func main() {
  func (msg string) {
    fmt.Println(msg)
  }("Hello World")
}

//〜出力〜
//Hello World

変数に関数を入れる

import "fmt"

func main() {
  h := func() {
    fmt.Println("Hello World")
  }
  h()
}

//〜出力〜
//Hello World

条件文

if文

import "fmt"

func main() {
  score := 70
  if 80 < score {
    fmt.Println("Great!")
  } else if 50 < score {
    fmt.Println("Good!")
  } else {
    fmt.Println("Bad")
  }
}

//〜出力〜
//Good!

そのif文の中だけで評価する変数をつかう

import "fmt"

func main() {
  if score := 70; 80 < score {
    fmt.Println("Great!")
  } else if 50 < score {
    fmt.Println("Good!")
  } else {
    fmt.Println("Bad")
  }

  fmt.Println(score)//⬅︎「score」っていう変数ないよ!っていうエラーがでる。
}

//〜出力〜
//Good!

switch文

import "fmt"

func main() {
  score := 70
  switch {
  case 80 < score:
    fmt.Println("Great!")
  case 50 < score:
    fmt.Println("Good!")
  default:
    fmt.Println("Bad")
  }
}

//〜出力〜
//Good!

map※rubyだとハッシュ

import "fmt"

func main() {
  m := map[int]string{1: "田中", 2: "鈴木", 3: "佐藤", 4: "渡辺"}
  fmt.Println(m)
  fmt.Println(m[1])
}

//〜出力〜
//map[1:田中 2:鈴木 3:佐藤 4:渡辺]
//田中
//4

mapの作り方としては map[キーの型]バリューの型 と宣言して後はハッシュ(他の言語だと連想配列)と同じように宣言する。

スライス※rubyだと配列

注意!!! Goにもスライスとは別に配列そのものは存在しますがGoでは配列とほぼ同じ使い方が出来てなおかつ使い勝手もいいスライスが使われることが多いみたいです(間違ってたら指摘お願いします。)なので最初はスライス==配列ということにします

import "fmt"

func main() {
  c := []int{1, 3, 7}
  fmt.Println(c)
}

//〜出力〜
//[1 3 7]

スライスの作り方としては []配列の型{} として後はコロンで要素を区切って作る

range※rubyだとeach文

import "fmt"

func main() {
  s := []int{1, 3, 7}//スライスを作成

  for i, v := range s {
    fmt.Println(i, v)
  }
}

//〜出力〜
//0 1
//1 3
//2 7

rangeは返り値としてインデックス番号と値を返します。今回はiでインデックス番号、vで要素の値を受け取っています。
また仮に配列の要素のみ使いたい場合は for _, v := range c {とする事でインデックス番号を無視してくれます

for文

import "fmt"

func main() {
  for i := 1; i < 100; i++ {
    fmt.Println(i)
  } 
}

//〜出力〜
//1
//2
//3
//・
//・
//・
//99


//条件をいれないと無限ループする
for {
  fmt.Println("Hello world")
}

//〜出力〜
//Hello world
//Hello world
//Hello world
//Hello world
//・
//・
//・

while文っぽくもかける

でも、GOにwhile文は存在しない

import "fmt"

func main() {
  sum := 1
  for sum < 30 {
    sum += sum
    fmt.Println(sum)
  }
}

//〜出力〜
//2
//4
//8
//16
//32

構造体(struct)

イメージとしてはrailsのmodelみたいな感じ

import "fmt"

//railsのmigration fileのように[カラム名 データ型]という形で定義 
type User struct {
  Name  string
  Age   int
}

func main() {
  //railsでデータをcreateするときのparamsと同じような形で定義
  user1 := User{Name: "kosuke", Age: 21}
  fmt.Println(user1)

  //そのデータに紐づく値を持ってくるときに 「.」区切りで値を参照できる
  fmt.Println(user1.Name)
  fmt.Println(user1.Age)
}

//〜出力〜
//{kosuke 21}
//kosuke
//21

ただ、↑でいっていることはあくまでイメージの話でgoの構造体はあくまでデータ型の1つであるのでその点は忘れないこと!

構造体の値をメソッドを使って変える

import "fmt"

type User struct {
  Name  string
  Age   int
}

func (u *User) changeName(string){
  u.Name = "Yamada"
}

func main() {
  user1 := User{Name: "kosuke", Age: 21}
  fmt.Println(user1.Name)

  user1.changeName(user1.Name)
  fmt.Println(user1.Name)
}

//〜出力〜
//kosuke
//Yamada

メソッドの定義方法は
func (メソッド内での変数名 *構造体名) メソッド名(このメソッド内の引数の変数 引数のデータ型)
となっています。
また、重要なのは構造体名の前についている「*」でこれを書くことでポインタを渡すことができます。
ポインタってなんぞ?って人は下の記事が個人的にはわかりやすかったのでこちらを参照してください。

【Go言語入門】構造体とポインタについて

ざっくりとした認識としては
「とりあえず生成した構造体をメソッド使って値を変更させたいときは「*」つければいいんだな」

って思っておけばいいと思います。

インターフェース

import "fmt"

//メソッド名(引数の型, ...) (返り値の型, ...)
type Human interface{
  Say() string
}

type Person struct {
  Name  string
}

func (u *Person) Say() string{
  u.Name = "Mr." + u.Name
  return u.Name
}

func main() {
  var user1 Human = &Person{Name: "kosuke"}
  fmt.Println(user1.Say())
}


//〜出力〜
//Mr.kosuke

インターフェイスとはメソッドの型です。
詳しくは↓
【Golang】Golangのinterfaceで知っておくとお得なTips

並行処理

import (
  "fmt"
  "time"
)

func hello()  {
  fmt.Println("hello")
}

func world()  {
  fmt.Println("world")
}

func main() {
  go hello()
  go world()

  time.Sleep(3 * time.Second)//3秒間動きを止める処理
}

//〜出力〜
//hello
//world

//または
//world
//hello

プログラムのコードは普通上から順番に読まれていきますが、Goでは
go hogehoge
とすることで同時に処理を行うことができます。
しかし、並行処理をしている間にプログラムそのものが終了してしまう可能性もあります。

それを回避するためには以下のように"sync"をimportして使用することで回避することができる

import (
  "fmt"
  "sync"
)

func hello(wg *sync.WaitGroup)  {
  defer wg.Done()//deferはその関数内で一番最後に呼ばれるようにするメソッド
  fmt.Println("hello")
}
func world()  {
  fmt.Println("world")
}

func main() {
  var wg sync.WaitGroup
  wg.Add(1)

  go hello(&wg)
  go world()

  wg.Wait()//「wg.Done()」が呼ばれるまで処理をストップ
}
5
2
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
5
2