0
0

More than 1 year has passed since last update.

Goアウトプット #01

Last updated at Posted at 2022-01-18

多重代入

var a, b, c int
a, b, c = 10, 20, 30

または

a, b, c := 10, 20, 30

同じ型の複数宣言

  • 初期化した値はゼロ値と呼ばれる。
    ※数値の場合は0
func main() {
    var (
        x int = 100
        y int = 300
        z int
    )
    // zは初期化されているだけなので、0になる

    fmt.Println("x + y + z =", x+y+z)
}

// -> 400

iota識別子

  • 連続した整数型整数を表現することができる
    ※変数でやったらエラーでた。←定数宣言でしか使えないから、そりゃそう。
func main() {
    const (
        x = iota
        y
        z
    )
    fmt.Println(x, y, z) 
}

// -> 0 1 2
func main() {
    const (
        x = 1
        y = iota
        z
    )
    fmt.Println(x, y, z) 
}

// -> 1 1 2
func main() {
    const (
        x = 10
        y = iota + 10
        z
    )
    fmt.Println(x, y, z) 
}

// -> 10 11 12
func main() {
    const (
        x = iota * iota
        y
        z
        zz
    )
    fmt.Println(x, y, z, zz) 
}

// -> 0 1 4 9

条件分岐(switch-case)

  • fallthroughを使用すれば、直下の処理が実行される
    └必ずcase文の最後に記述。
  • 論理値、文字列を使用することができる
func main() {
    value := 1
    switch value {
    case 1:
        fmt.Println("value = 1")
        fallthrough
    case 2:
        fmt.Println("value = 2 or 3")
    default:
        fmt.Println("value = other")
    }
} 

//-> value = 1
//   value = 2 or 3
func main() {
    value := 15
    switch {
    case value > 0 && value <= 10:
        fmt.Println("1 ~ 10")
    case value > 10 && value <= 20:
        fmt.Println("11 ~ 20")
    case value > 20 && value <= 30:
        fmt.Println("21 ~ 30")
    default:
        fmt.Println("other")
    }
}

// -> 11 ~ 20
func main() {
    value := "XYZ"
    switch value {
    case "ABC":
        fmt.Println("ABC")
    case "LMN":
        fmt.Println("LMN")
    case "XYZ":
        fmt.Println("XYZ")
    default:
        fmt.Println("other")
    }
}

// -> "XYZ"

繰り返し(for)

  • break
    └ループ処理を強制的に抜ける
  • continue
    └ループブロックの処理をスキップする
func main() {
    i := 0
    for {
        if i == 20 {
            break
        }
        fmt.Println(i)
        i++
    }
}

// -> 1.....19
func main() {
    value := 0
    for {
        if value%2 == 0 {
            fmt.Println(value)
            value++
        } else {
            value++
            continue
        }
        if value > 10 {
            fmt.Println("")
            break
        }
    }
}

//-> 0
//   2
//   4
//   6
//   8
//   10

データ型

文字列型

  • インデックスに保存されるバイト数は文字によって異なる。
    └漢字はものによって4バイト使用するものがある。
func main() {
    str := "abcあいうえお"
    for index, codepoint := range str {
        result := fmt.Sprintf("index=%d, rune=%d, string=%s", index, codepoint, string(codepoint))
        fmt.Println(result)
    }
}

// -> index=0, rune=97, string=a
//  index=1, rune=98, string=b
//  index=2, rune=99, string=c
//  index=3, rune=12354, string=あ
//  index=6, rune=12356, string=い
//  index=9, rune=12358, string=う
//  index=12, rune=12360, string=え
//  index=15, rune=12362, string=お

len()関数

  • 文字列や配列のバイト数を取得する時に使用する
func main() {
    str1 := "ABC"
    str2 := "あいう"
    fmt.Println(len(str1), len(str2))
}

// -> 3 9

RuneCountInString()関数

  • 文字数を取得する時に使用する
  • unicode/utf8パッケージを読み込む必要がある
import (
    "fmt"
    "unicode/utf8"
)

func main() {
    str1 := "ABC"
    str2 := "あいう"
    fmt.Println(utf8.RuneCountInString(str1), utf8.RuneCountInString(str2))
}

// -> 3 3

strconvパッケージ

Itoa()関数

  • int型整数を文字列に変換する
func main() {
    x := 12345
    fmt.Println(strconv.Itoa(x))
}

// -> 12345 ※文字列

配列

  • デフォルトではゼロ値で初期化される。
  • [...]で指定すると、初期化の際に設定されて要素数が自動的に配列の長さになる。
func main() {
    var array [3]int
    for _,value := range array {
        fmt.Println(value)
    }
    fmt.Println("-----")

    array[0] = 100
    array[1] = 200
    array[2] = 300
    for _, value := range array {
        fmt.Println(value)
    }
}
// -> 0
//  0
//  0
//  -----
//  100
//  200
//  300

スライス

  • ポインタ(ptr)、長さ(len)、容量(cap)からデータ構造を保持している
  • 長さをlen()関数、容量をcap()関数で取得できる
  • 配列からスライスを作成するだけでなく、スライスからスライスを作成することができる
    ※スライスは参照型
// スライス構造体
type SliceHeader struct {
  Data unitptr  //配列の参照
  Len  int      //長さ
  Cap  int      //容量
}

配列からの取得

スライス := 配列またはスライス[下限:上限]

※個人的にいいと思った考え方は:をスライスと捉える。
x:だとx以降のスライス。:xだとxまでのスライス。
※下限は含み、上限は含まない

func main() {
    array := [...]string{"A", "B", "C", "D", "E"}
    slice1 := array[:]
    slice2 := array[1:3]
    slice3 := array[:3]
    fmt.Println("参照(Data) ", slice1, slice2, slice3)
    fmt.Println("長さ(Len)  ", len(slice1), len(slice2), len(slice3))
    fmt.Println("容量(Cap)  ", cap(slice1), cap(slice2), cap(slice3))
}

// -> 参照(Data)  [A B C D E] [B C] [A B C]
//    長さ(Len)   5 2 3
//    容量(Cap)   5 4 5

容量(capacity)

  • スライス全体の容量を表す。
  • append()で参照元の容量を越すと、倍の容量になる

make()関数

  • 配列とスライスを同時に作成することができる
  • マップやチャネルを作成する時にも利用される

make([]配列の型, 長さ [,容量])

func main() {
    slice1 := make([]int, 3)
    slice2 := make([]int, 3, 5)
    fmt.Println(slice1, slice2)
    fmt.Println(len(slice1), len(slice2))
    fmt.Println(cap(slice1), cap(slice2))
}

// -> [0 0 0] [0 0 0]
//  3 3
//  3 5

append()関数

  • スライスに値を追加する時に使用する
  • 追加することはできるが、削除することはできない。
func main() {
    slice1 := make([]int, 3, 5)
    slice1 = append(slice1, 100, 200)
    fmt.Println(slice1, len(slice1), cap(slice1))

    slice2 := make([]int, 2)
    slice2[0] = 1000
    slice2[1] = 2000
    fmt.Println(slice2, len(slice2), cap(slice2))

    slice3 := append(slice1, slice2...)
    // slice1の方にslice2を追加するイメージ
    // 容量もslice1に合わせた形になるため、5*2の10になる
    fmt.Println(slice3, len(slice3), cap(slice3))
}

// -> [0 0 0 100 200] 5 5
//  [1000 2000] 2 2
//  [0 0 0 100 200 1000 2000] 7 10

copy()関数

  • スライスの値をコピーすることができる
    ※下限や上限を設定すれば、コピーする部分を指定することができる
func main() {
    slice1 := []int{100, 200}
    slice2 := []int{201, 202, 203, 204}
    fmt.Println(slice1, slice2)

    copyCount := copy(slice2, slice1)
    // slice2にslice1をコピーするイメージ
    // copyCountはコピーした要素を入れた変数のみ。変数を宣言しなくてもコピーはできる
    fmt.Printf("%v コピーした要素の数=%d \n", slice2, copyCount)
}

// -> [100 200] [201 202 203 204]
//    [100 200 203 204] コピーした要素の数=2
func main() {
    slice1 := []int{100, 200}
    slice2 := []int{201, 202, 203, 204}
    fmt.Println(slice1, slice2)

    copyCount := copy(slice2[3:], slice1)
    fmt.Printf("%v コピーした要素数=%d \n", slice2, copyCount)
}

// -> [100 200] [201 202 203 204]
//    [201 202 203 100] コピーした要素数=1
func main() {
    slice1 := []int{100, 200}
    slice2 := []int{201, 202, 203, 204}
    fmt.Println(slice1, slice2)

    copyCount := copy(slice2[:1], slice1)
    fmt.Printf("%v コピーした要素数=%d \n", slice2, copyCount)
}

// -> [100 200] [201 202 203 204]
//    [100 202 203 204] コピーした要素数=1
func main() {
    slice1 := []int{100, 200}
    slice2 := []int{201, 202, 203, 204}
    fmt.Println(slice1, slice2)

    copyCount := copy(slice2[1:3], slice1)
    fmt.Printf("%v コピーした要素数=%d \n", slice2, copyCount)
}

// -> [100 200] [201 202 203 204]
//    [201 100 200 204] コピーした要素数=2

値の削除を行う関数はサポートされていないので、関数を自作する必要がある。

func DeleteSlice(slice []int, i int) []int {
    slice = append(slice[:i], slice[i+1:]...)
    newSlice := make([]int, len(slice))
    copy(newSlice, slice)
    return newSlice
}

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice, len(slice), cap(slice))
    slice = DeleteSlice(slice, 1) 
  //1番目の値を削除する
    fmt.Println(slice, len(slice), cap(slice))
}

// -> [1 2 3 4 5] 5 5
//    [1 3 4 5] 4 4
0
0
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
0
0