モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)
目次目次を開く/閉じる

Go 言語の基本的な使い方

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2020/09/02
最終更新最終更新
2023/01/18
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    Pythonでデータ解析と自動化ツールを開発しています。DjangoでのWeb開発も得意です!

    0
    ステッカーを贈るとは?

    Go 言語に関する基本的な事項を記載します。

    モジュール、パッケージ、ライブラリ、アプリケーション

    一つ以上の関数をまとめたものをパッケージとして利用します。更に一つ以上のパッケージをまとめたものをモジュールとして利用します。モジュールにはライブラリとして機能するものと、アプリケーションとして機能するものがあります。

    以下の例では myappmylib モジュールの二つを作り、myapp から mylib を利用します。

    モジュールの新規作成

    ライブラリとして機能するモジュール

    mkdir mylib
    cd mylib
    go mod init mylib
    

    アプリケーションとして機能するモジュール

    mkdir myapp
    cd myapp
    go mod init myapp
    

    以下のようなファイルが作成されます。

    $ cat go.mod
    module mylib
    
    go 1.15
    

    ライブラリとして機能するモジュール内に二つのパッケージを作成

    mylib ディレクトリに以下のような二つのパッケージを作成してみます。パッケージ名はモジュール名と一致している必要はありません。また、ファイル名はパッケージ名と一致している必要はありません。同じパッケージのソースコードは同じディレクトリに存在している必要があります。

    mylib/mylib.go

    package mylib
    
    import "fmt"
    
    func Hello() {
    fmt.Println("hello from mylib")
    }
    

    mylib/bbb.go

    package mylib
    
    import "fmt"
    
    func Hello2() {
    fmt.Println("hello2 from mylib")
    }
    

    mylib/aaa/aaa.go

    package aaa
    
    import "fmt"
    
    func Hello() {
    fmt.Println("hello from aaa")
    }
    

    mylib/aaa/bbb.go

    package aaa
    
    import "fmt"
    
    func Hello2() {
    fmt.Println("hello2 from aaa")
    }
    

    アプリケーションとして機能するモジュールに main パッケージを作成

    エントリポイントとなるパッケージは main とする必要があります。

    myapp/myapp.go

    package main
    
    import (
    "mylib"
    "mylib/aaa"
    )
    
    func main() {
    mylib.Hello()
    mylib.Hello2()
    aaa.Hello()
    aaa.Hello2()
    }
    

    mylib モジュールを import するために、ここでは go.mod を以下のように書き換えます。

    myapp/go.mod

    module myapp
    
    go 1.15
    
    replace mylib => ../mylib
    

    ビルド

    スクリプト言語のように実行する場合

    go run myapp.go
    
    hello from mylib
    hello2 from mylib
    hello from aaa
    hello2 from aaa
    

    ビルドして実行する場合

    go build
    cp myapp /tmp/
    cd /tmp/
    ./myapp
    
    hello from mylib
    hello2 from mylib
    hello from aaa
    hello2 from aaa
    

    いずれの場合も、初回実行時は mylib のチェックサムが go.mod に追記されます。

    go: found mylib in mylib v0.0.0-00010101000000-000000000000
    go: found mylib/aaa in mylib v0.0.0-00010101000000-000000000000
    

    myapp/go.mod

    module myapp
    
    go 1.15
    
    replace mylib => ../mylib
    
    require mylib v0.0.0-00010101000000-000000000000
    

    変数、fmt

    var a, b int
    a, b = 1, 2
    

    初期値を指定する場合は以下のようにします。

    var a, b int = 1, 2
    

    初期値が存在する場合は型は省略可能です。Scala 等の他の言語のように型推論が行われます。

    var a, b = 1, 2
    fmt.Println(reflect.TypeOf(a)) //=> int
    

    func 内であれば var:= 記法で省略できます。

    a, b := 1, 2
    

    初期化されていない変数の初期値は以下のようになります。

    • 数値 → 0
    • 真偽値 → false
    • 文字列 → ""

    型のキャストは以下のようにします。

    i := 123
    f := float64(i)
    

    定数は const で宣言します。

    const Pi = 3.14
    

    関数

    func MyFunc(myarg string) string {
        mystr := fmt.Sprintf("Hi, %v", myarg)
    return mystr
    }
    
    fmt.Println(MyFunc("myarg"))  //=> Hi, myarg
    

    なお、大文字で始まる変数および関数はパッケージの外からでも利用できます。

    同じ型の引数については、型をまとめて記載できます。また、返り値に名前を付けておくことで return する変数を指定できます。ただし、これは長い関数については可読性を落とす可能性があります。

    package main
    
    import (
    "fmt"
    )
    
    func MyFunc(x, y string) (a, b string) {
    a = y
    b = x
    return
    }
    
    func main() {
    fmt.Println(MyFunc("aaa", "bbb"))  //=> bbb aaa
    }
    

    関数を引数にする関数

    package main
    
    import (
    "fmt"
    )
    
    func MyFunc(fn func(string) string) {
    fmt.Println(fn("aaa"))
    }
    
    func main() {
    fn := func(str string) string {
    return str + "!"
    }
    MyFunc(fn)  //=> aaa!
    }
    

    クロージャ

    package main
    
    import (
    "fmt"
    )
    
    func MyFunc() func() int {
    cnt := 0
    return func() int {
    cnt++
    return cnt
    }
    }
    
    func main() {
    
    fn := MyFunc()
    
    fmt.Println(fn())  //=> 1
    fmt.Println(fn())  //=> 2
    fmt.Println(fn())  //=> 3
    }
    

    ログエラー

    package main
    
    import (
    "fmt"
    "errors"
    "log"
    )
    
    func MyFunc(myarg string) (string, error) {
    if myarg == "" {
    return "", errors.New("myarg is empty")
    }
    return "ok", nil
    }
    
    func main() {
    res, err := MyFunc("")
    
    if err != nil {
    log.Fatal(err)
    }
    
    fmt.Println(res)
    }
    

    実行例

    $ go run myapp.go
    2020/09/09 21:53:33 myarg is empty
    exit status 1
    
    $ echo $?
    1
    

    乱数時間可変長配列 (スライス)

    init() 関数は、プログラム開始されてグローバル変数が初期化された後に、自動的に実行されます

    package main
    
    import (
    "fmt"
    "math/rand"
    "time"
    )
    
    func init() {
    rand.Seed(time.Now().UnixNano())
    }
    
    func main() {
    myslice := []string{
    "aaa",
    "bbb",
    "ccc",
    }
    fmt.Println(myslice[rand.Intn(len(myslice))])
    }
    

    マップ

    package main
    
    import (
    "fmt"
    )
    
    func MyFunc(myargs []string) map[string]string {
    mymap := make(map[string]string)
    for _, myarg := range myargs {
    mymap[myarg] = myarg + "!"
    }
    return mymap
    }
    
    func main() {
    myslice := []string{
    "aaa",
    "bbb",
    "ccc",
    }
    mymap := MyFunc(myslice)
    fmt.Println(mymap["aaa"])  //=> aaa!
    }
    

    for ループにおけるインデックスが不要な場合は、上記のように _利用します

    要素の削除

    m := make(map[string]int)
    m["a"] = 123
    delete(m, "a")
    

    要素の存在確認

    elem, ok := m["a"]
    

    テスト正規表現

    mylib/mylib.go

    package mylib
    
    import "fmt"
    
    func Hello(myarg string) string {
    return fmt.Sprintf("hello %v !", myarg)
    }
    

    mylib/mylib_test.go

    package mylib
    
    import (
    "testing"
    "regexp"
    )
    
    func TestHello1(t *testing.T) {
    myarg := "aaa"
    want := regexp.MustCompile(`\b` + myarg + `\b`)
    res := Hello(myarg)
    
    if !want.MatchString(res) {
    t.Fatalf(`Hello(%q) = %q, want match for %#q`, myarg, res, want)
    }
    }
    

    実行例

    $ ls -l
    drwxr-xr-x   2 myuser       myuser 4096 2020-09-08 23:06 aaa
    -rw-r--r--   1 myuser       myuser   81 2020-09-08 23:06 bbb.go
    -rw-r--r--   1 myuser       myuser   22 2020-09-08 22:10 go.mod
    -rw-r--r--   1 myuser       myuser  106 2020-09-09 22:38 mylib.go
    -rw-r--r--   1 myuser       myuser  273 2020-09-09 22:39 mylib_test.go
    
    $ go test
    PASS
    ok  
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    Pythonでデータ解析と自動化ツールを開発しています。DjangoでのWeb開発も得意です!

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。