Dragon Arrow written by Tatsuya Nakaji, all rights reserved animated-dragon-image-0164

go言語 変数と定数

Oct 17, 2020

変数と定数



基礎知識

  • メモリ上で管理されている値を保持する領域

    • 識別子(変数名)で識別される

    • 処理中に一時的に値を保存しておくために必要

    • メモリ上にある値なのでマシンが止まると消える(揮発性)

    • プログラムの実行が終わると消える

    • 結果を残したい場合はファイルなど外部記憶装置上で管理される領域や出力装置(プリンタなど)経由で出力する必要がある


変数と型

    • どういう種類の値かを表すもの

      • 整数、浮動小数点数、真偽値、文字列 など

      • 自分で作ることも可能(ユーザ定義型)

    • 変数の型:どういう種類の値が入るのかを表したもの

  • 動的型付け言語

    • Ruby, Python, PHPなど

    • プログラム実行時に型を検証する

    • 変数に型がなく、なんでも代入できる

  • 静的型付け言語

    • GoやC, java, TypeScriptなど

    • コンパイル時に型を検証する

    • 変数に型がある、型が違うと代入できない


Goの型付け

  • 実行前に型の不一致を検出できる

    • コンパイルが通れば型の不一致が起きない

    • 型の不一致によるバグは見つけづらい問題

  • 曖昧なものはエラーになる

    • 暗黙の型変換がない

      • 1 + "2" => "12"(JavaScript)

    • 浮動小数点数と整数の演算など見つけづらいバグが起きにくい

  • 型推論がある

    • 明示的に型を書く必要がない場合が多い


変数定義


・変数定義と代入が一緒

var n int = 100


・変数定義と代入が別

var n int
n = 100


・型を省略(int型になる)

var n = 100


varを省略 (注意)関数内のみでしかできない

n := 100


まとめて定義

var (
    n = 100
    m = 200
)


整数

int, int8, int16, int32, int64,

uint, uint8, uint16, uint32, uint64,

uintptr, byte, rune

浮動小数点数

float32, float64

複素数

complex64, complex128

文字列

string

真偽値

bool

エラー

error


変数のゼロ値


Goの変数は明示的な初期化をしなくてもゼロ値で初めから初期値されている

ゼロ値

intやfloat64などの数値

0

string

""

bool

false

error

nil


定数

  • 値の変わらないもの

    • コンパイル時から値が変わらないもの

    • リテラルで記述されることが多い

 

種類

数値リテラル

100, 1.5, 1+4i

文字列リテラル

"hoge"

ルーンリテラル

'A', '世'

真偽値リテラル

true, false



定数式

定数のみからなる演算式 


ビット演算子

「>>」と「<<」はビット演算子と呼ばれているもので、数値を二進数であらわしたときに右にずらしたり左にずらしたりするものです。

たとえば十進数の5を二進数であらわすと101になります。
そこで左にずらしてみます。
101 << 1 → 1010(二進数)で十進数だと10です。
101 << 3 → 101000(二進数)で十進数だと40です。

今度は右にずらしてみます。
101 >> 1 → 10(二進数)で十進数だと2です。
101 >> 2 → 1(二進数)で十進数でも1です。

種類

演算結果

四則演算

100 + 200

300

シフト演算

1 << 2

4

文字列結合

"Hello, " + "世界"

"Hello, 世界"

関係演算/論理演算

!(10 == 20)

true



名前付き定数


・型のある定数

const n int = 100


・型のない定数

const m = 100


・定数式の使用

const s = "Hello, " + "世界"


まとめて定義

const (
    x = 100
    y = 200
)


定数の型


  • 型を持たない定数

    • 型を明示しない場合に定数は型を持たず、デフォルトの型を持つ

 

種類

デフォルトの型

整数

100

int

浮動小数点数

1.5

float64

複素数

1+4i

complex128

ルーン

'A', '世'

rune

文字列

"hoge"

string

真偽値

true

bool



定数のデフォルトの型


  • 変数に代入される場合はデフォルトの型になる

    • 型推論ではデフォルトの型として推論される

    • 型が指定されている変数への代入はその型になる

    • 変数や型のある定数との演算はそれらの型になる

      • キャストできない場合はコンパイルエラーになる

package main


func main() {
    // 定数は型を持たないので無限の精度になる
    const n = 10000000000000000000 / 10000000000000000000
    var m = n  // mはint型
    println(m) // 1
}


右辺の省略


  • 名前付き定数定義の右辺が省略できる

    • グループ化された名前付き定数で用いられる

    • 2つめ以降の名前付き定数の右辺を省略できる

    • 2つめ以降の定数定義の右辺は、1つめの定数の右辺と同じになる



func main() {
    const (
        a = 1 + 2
        b // 省略したら、1つ目の定義と同じになる
        c // 省略したら、1つ目の定義と同じになる
    )
    fmt.Println(a, b, c) // 全部3になる
}


iota

  • 連続した定数(const)を作るための仕組み

    • グループ化された名前付き定数の定義で使われる

    • 0から始まり1ずつ加算される値として扱われる



package main


import "fmt"

func main() {
    const (
        a = iota # 0
        b # b = iota と同じで1
    )
    const (
        c = 1 << iota # 1 << 0 なので1
        d # 1 << 1 なので2
        e # 1 << 2 なので4
    )
    fmt.Println(a, b, c, d, e)
}

(出力)

0 1 1 2 4