LoginSignup
0

More than 3 years have passed since last update.

Go言語に触れてみよう Part.2

Posted at

はじめに

前回からだいぶ時間が経ってしまいました。。。

今回は、Tour of Goに触れていきながらGoの文法・構文についてみていきます。

Tour of Go

以下からサイトに飛んでください。
Tour of Go

Tour of Goの日本語訳なのでかなり読みやすくわかりやすいです。
また、Go言語を学ぶためにはかなりいい教材だと思っています。

では、演習をみていきましょう!!
(全ての演習をやっていきません。ごめんなさい。。。)

Package・Import

演習前に基本的な文法をおさらいします。

基本的にpackageについてはmain

ただ、ディレクトリ管理によってはpackege名を変える必要があるため、
Go言語のWebアプリ開発で注意。

importはGo言語ではグループ化があります。

import (
    "string"
    . "fmt"
    m "math"   
)

"fmt"と"math"の書き方は、それぞれドット操作エイリアス操作といいます。
こうすることで、fmtパッケージやmathメソッドを呼び出す際に省略・簡略可能になります。

fmt.Println("hoge")

Println("hoge") // 省略

math.Abs(-12.34)

m.Abs(-12.34) // 簡略

Exercise: Loops and Functions

色々進めていくと、関数や変数宣言、for・while・if文が紹介されます。

初めの演習問題は、平方根の計算をmathメソッドを使わずに実装するものです。
ヒントとして、z -= (z*z - x) / (2*z)z := 1.0 or z := float64(1)
を使用したらできるそうです。

また、指定として10回ループしてから、結果を出します。

exercise-loops-and-functions.go
package main

import (
    "fmt"
)

func Sqrt(x float64) float64 {
    // z := 1.0
    z := float64(1)

    for i := 0; i < 10; i++ {
        z -= (z*z - x) / (2*z)
    }
    return z
}

func main() {
    fmt.Println(Sqrt(2))
}

Exercise: Slices

演習を終えると、switch文やdefer、pointer、Array・Sliceなどの説明があります。ここから初心者の方は難しくなっていきます。

pointerに関しては、C言語での勉強をお勧めします。

ここでの演習は、Sliceでの2次元配列を使用して画像を表示するものです。

exercise-slices.go
package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    pic := make([][]uint8, dy)
    for y := range pic {
        pic[y] = make([]uint8, dx)
        for x := range pic[y] {
            pic[y][x] = uint8((x + y) / 2)
            // pic[y][x] = uint8(x * y)
            // pic[y][x] = uint8(x ^ y)
        }
    }
    return pic
}

func main() {
    pic.Show(Pic)
}

Exercise: Maps

続いては、mapです。
扱いについては、ArrayやSliceと似ている部分があるため、
そんなに難しくはありません。

演習では、mapを使用してテストケースをしっかりと走らせるものです。
ここで、stringsのメソッドを使用して引数に渡った文字列を分解していきます。

exercise-maps.go
package main

import (
    "strings"

    "golang.org/x/tour/wc"
)

func WordCount(s string) map[string]int {
    words := make(map[string]int)
    for _, i := range strings.Fields(s) {
        words[i]++
    }
    return words
}

func main() {
    wc.Test(WordCount)
}

Exercise: Fibonacci closure

関数のクロージャーについて学びます。

演習は、Fibonacci数列を実装します。
Fibonacci数列は、「2つ前の項と1つ前の項を足し合わせていくことでできる数列」のことです。
1, 1, 2, 3, 5, 8, 13, 21 ...

これをクロージャーでやっていきます。

exercise-fibonacci-closure.go
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a, b := 0, 1
    return func() int {
        a, b = b, a+b
        return a
    }
}

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

Exercise: Stringers

ここからは関数とメソッドの違いやpointerとの関係、interfaceなどを学んでいきます。少し難しくなっていきます。

演習では、interfaceの一つであるfmt内のStringerを使用して、
IPアドレスを出力します。

exercise-stringers.go
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.
func (addr IPAddr) String() (s string) {
    for _, v := range addr {
        s += fmt.Sprintf("%d.", v)
    }
    return s[:len(s)-1]
}

func main() {
    hosts := map[string]IPAddr{
        "loopback":  {127, 0, 0, 1},
        "googleDNS": {8, 8, 8, 8},
    }
    for name, ip := range hosts {
        fmt.Printf("%v: %v\n", name, ip)
    }
}

Exercise: Errors

ここでは、Go言語におけるエラーハンドリングを学びます。

exercise-errors.go
package main

import (
    "fmt"

)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %f", float64(e))
}

func Sqrt(x float64) (float64, error) {
    if x < 0 {
        return 0, ErrNegativeSqrt(x)
    }
    // z := 1.0
    z := float64(1)

    for i := 0; i < 10; i++ {
        z -= (z*z - x) / (2*z)
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}

Exercise: Readers

ioパッケージのReaderinterfaceを使ってioデータを読み取ります。

exercise-readers.go
package main

import "golang.org/x/tour/reader"

type MyReader struct{}

// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (a MyReader) Read(rb []byte) (n int, e error) {
    for i, _ := range rb {
        rb[i] = 'A'
        n++
    }
    return
}

func main() {
    reader.Validate(MyReader{})
}

Exercise: rot13Reader

前の演習と同じような感じでReaderinterfaceを使用します。

exercise-rot13reader.go
package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (a *rot13Reader) Read(rb []byte) (n int, e error) {
    n, e = a.r.Read(rb)
    if e == nil {
        for i, v := range rb {
            switch {
            case v >= 'A' && v <= 'Z':
                rb[i] = (v-'A'+13)%26 + 'A'
            case v >= 'a' && v <= 'z':
                rb[i] = (v-'a'+13)%26 + 'a'
            }
        }
    }

    return
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)

    s2 := strings.NewReader("You cracked the code!")
    r2 := rot13Reader{s2}
    io.Copy(os.Stdout, &r2)
}

Exercise: Images

今までの3つでinterfaceの使い方を学ぶものなので、readerと同じように書きます。

exercise-images.go
package main

import (
    "golang.org/x/tour/pic"
    "image"
    "image/color"
)

type Image struct{}

func (im Image) ColorModel() color.Model {
    return color.RGBAModel
}

func (im Image) Bounds() image.Rectangle {
    return image.Rect(0, 0, 255, 255)
}

func (im Image) At(x, y int) color.Color {
    v := uint8(x * y)
    return color.RGBA{v, v, 255, 255}
}

func main() {
    m := Image{}
    pic.ShowImage(m)
}

終わり

これでとりあえずの基本的なことができるようになると思います。
もっと深くやりたい人は、次の章に進んでください。

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
0