20210226のGoに関する記事は2件です。

プログラミング超入門(1)〜GO言語〜

Visual Studio Code(ビジュアル スタジオ コード)略してvscodeをインストールしてプログラムを実行してみる。

vs.png
まず、Japanese Language Pack for Visual Studio Code(日本語翻訳)とGo言語の拡張機能を
vscode内でインストールしましょう。
vs2.png
新規フォルダからファイルを作成し、run.goという名前でコードを書いてみましょう。名前のrunは実行を意味し、( . )ピリオドの後に拡張子のgoを付けることで、Go言語だと自動的に判断してくれます。


run.go
package main

import "fmt"

func main() {
    var a int
    a = 3
    fmt.Println(2 * a)
}

前回の記事で説明した続きになりますが、var a intはそれぞれ意味を持っていて、
var予約語(あらかじめ定められた役目を持った単語)であり、packageimport
それに当たります。予約語は変数名として使用することは出来ません。そしてvar
変数名を宣言する(変数であることを示す)為に使われ、aが変数名に当たります。
次にintデータ型(あるデータを保持しておく為に必要なメモリ領域の大きさ)を指します。
変数とは文字や数字などのデータを入れて置くことができるのようなもので、必要な
時にいつでもデータを取り出すことができます。変数にデータを入れることを代入
いい、データを取り出すことを参照といいます。初めて変数にデータを入れることを
変数の初期化といい、変数を宣言する(変数を作る)作業に繋がります。変数a=3
代入し、文字列や変数の中身を参照させる為に、Println(プリントライン関数を使います。
この変数の宣言と同時にデータを省略し代入することも可能です。

run.go
package main

import "fmt"

func main() {
    var a = 3
    fmt.Println(2 * a)
}

まずは省略してみます。変数aの後にいきなり3を代入してあります。Goが自動的に
データ型を判断してくれているので上記と同じ結果が返ってきます。

run.go
package main

import "fmt"

func main() {
    a := 3
    fmt.Println(2 * a)
}

更にシンプルに変数名a コロン: イコール= 代入したい値3で変数の宣言と同時に代入させ
る宣言方法がGoではよく使用されています。ファイルを保存し、ターミナルを開いて実行してみましょう。

・実行結果

go build run.go

6

go buildの後にファイル名run.goエンターして、./intsでエンターキーで、ビルド・実行
[ 6 ]が表示されました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

取り出したデータを条件分岐してGoの多次元スライスに入れる方法

はじめに

DBから取り出したデータを多次元構造にしてから処理する必要があったので実装を考えてみました。
例えば教科・科目を持つ学生のテーブルがあるとして、同じ教科・科目の組み合わせを持つ学生を同じ配列のなかに入れたいとします。

プログラム

package main

import (
    "fmt"
    "sort"
)

type student struct {
    studentID       uint64
    subjectAreaCode string
    subjectCode     string
}

func main() {
    // テストデータ
    students := []student{
        {1, "001", "002"},
        {2, "002", "003"},
        {3, "003", "004"},
        {4, "004", "005"},
        {5, "001", "005"},
        {6, "003", "004"},
        {7, "004", "005"},
    }

    // あとで隣り合うものを比較するため一旦並び替える
    sort.Slice(students, func(i, j int) bool {
        return students[i].subjectAreaCode < students[j].subjectAreaCode
    })
    sort.Slice(students, func(i, j int) bool {
        return students[i].subjectCode < students[j].subjectCode
    })

    // 初期化
    multiStudents := make([][]*student, len(students))
    var ac1, ac2 string // 教科コード
    var c1, c2 string   // 科目コード

    var n int

    // 教科・科目ごとに分類(多次元スライス)
    for i, h := range students {
        // 最初の要素は普通に入れる
        if i == 0 {
            multiStudents[n] = append(multiStudents[n], &h)
            ac1 = h.subjectAreaCode
            c1 = h.subjectCode
            continue
        }

        ac2 = h.subjectAreaCode
        c2 = h.subjectCode

        if ac1 == ac2 && c1 == c2 {
            multiStudents[n] = append(multiStudents[n], &h)
        } else {
            n++
            multiStudents[n] = append(multiStudents[n], &h)
        }
        ac1 = h.subjectAreaCode
        c1 = h.subjectCode
    }

    // 空要素を取り除く
    var m [][]*student
    for _, v := range multiStudents {
        if len(v) > 0 {
            m = append(m, v)
        }
    }
    // 出力確認
    for _, v := range m {
        fmt.Println(v)
    }

    // この後処理が続く

    return
}

プレビュー

解説

スライスを初期化して、取り出したデータ分の長さと容量を確保します。

multiStudents := make([][]*student, len(students))

最初のループでは要素はそのまま格納し、その教科・科目コードを変数に入れます。
2回目以降のループでは比較する教科・科目コードを別の変数に入れ、両方一致する場合は同じ要素のスライスに入れます。一致しない場合は次の要素のスライスに入れていきます。
ループで隣り合うもの同士を比較するため、前処理でソートしています。

for i, h := range students {
    if i == 0 {
        multiStudents[n] = append(multiStudents[n], &h)
        ac1 = h.subjectAreaCode
        c1 = h.subjectCode
        continue
    }

    ac2 = h.subjectAreaCode
    c2 = h.subjectCode

    if ac1 == ac2 && c1 == c2 {
        multiStudents[n] = append(multiStudents[n], &h)
    } else {
        n++
        multiStudents[n] = append(multiStudents[n], &h)
    }
    ac1 = h.subjectAreaCode
    c1 = h.subjectCode
}

改善したい点

上記の方法で初期化すると、場合によっては空要素ができてしまいます。

[{1 001 002}]
[{2 002 003}]
[{3 003 004} {6 003 004}]
[{5 001 005}]
[{4 004 005} {7 004 005}]
[]
[]

かといって初期化時に長さ・容量を確保しないと、最初のループで要素を格納するときにパニックになります。

var multiStudents [][]*student
multiStudents[n] = append(multiStudents[n], &h)
// => panic: runtime error: index out of range [0] with length 0

なので今回は仕方なくあとで空要素を取り除いて処理しています。
この部分をもっと綺麗にできないかと思っています。

まとめ

多次元構造でのスライス格納処理をしてみました。
ループのなかで比較する教科・科目コードを変数に入れていく位置がポイントでした。一致確認をする前に次の比較対象を入れ、一致確認後に今の比較対象をいれています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む