GO言語学習ノート#2    変数型②

##1、変数
### 1.4 基本データ型

①整数型

|データ型            |説明|
|:------------------|:------------------|
|uint8 |符号なし8 ビット整数型(0 ~ 255)
|uint16|符号なし16 ビット整数型(0 ~ 65535)
|uint32|符号なし32 ビット整数型(0 ~ 4294967295)
|uint64|符号なし64 ビット整数型(0 ~ 18446744073709551615)
|int8 |符号あり8 ビット整数型(-128 ~ 127)
|int16|符号あり16 ビット整数型(-32768 ~ 32767)
|int32|符号あり32 ビット整数型(-2147483648 ~ 2147483647)
|int64|符号あり64 ビット整数型(-9223372036854775808 ~ 9223372036854775807)


特殊整数型

|データ型            |説明|
|:------------------|:------------------|
|uint | 32bitシステムはuint32、64bitシステムはuint64
|int　|32bitシステムはint32、64bitシステムはint64
|uintptr|ポインタを格納するために使用される符号なし整数型

**注意事項：長さを取得するlen（）関数によって返される長さは、システムによって異なる場合がある。 実際の使用では、スライスまたはmapの要素の数はintで表すことができる。 バイナリ転送構造やファイル読み取り・書き込みに関しては、ファイルの構造を維持するために、異なるコンパイルターゲットプラットフォームのバイト長の影響を受けないように、intとuintを使用しないでください。**

八進法と十六進法および指数表記も使える。標準ライブラリのmathは各データ型の範囲を定義する。


```golang

package main

import (
	"fmt"
	"math"
)

func main() {
	a, b, c := 100, 0144, 0x64
	fmt.Println(a, b, c)
	fmt.Printf("0b%b, %#o, %#x\n", a, a, a)

	fmt.Println(math.MinInt8, math.MaxInt8)
}
```
出力

```
100 100 100
0b1100100,0144,0x64
-128 127
```

②浮動小数点数
Go言語は、float32とfloat64の2つの浮動小数点数をサポートしている。 これらの2つの浮動小数点数は、IEEE754標準に準拠している。float32浮動小数点数の最大範囲は約3.4e38で、定数math.MaxFloat32で定義できる。 float64 floatの最大範囲は約1.8e308で、定数math.MaxFloat64で定義できます。

fmtパッケージと％fをを使用して、浮動小数点数を出力する。

```go
package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Printf("%f\n", math.Pi)
	fmt.Printf("%.2f\n", math.Pi)
	fmt.Println(math.MaxFloat32)
	fmt.Println(math.MaxFloat64)
}
```

出力

```
3.141593
3.14
3.4028234663852886e+38
1.7976931348623157e+308
```
②別名型

公式標準では、二つの別名型を述べてある。

>byte    alias for uint8
>rune    alias for int32

別名型は変換する必要がない、値を直接的に与えることができる

```go

package main

import "fmt"

func test(x byte) {
	fmt.Println(x)
}

func main() {
	var a byte = 0x11
	var b uint8 = a
	var c uint8 = a + b

	test(c)
}
```
しかし、これは、同じ基本構造を持つものが別名型に属していることを意味するわけではない。64bitシステムはintとint64の構造が一致しても、異なる型に属している、明示的型変換しなければならない。





###1.5 参照型変数

参照型変数(reference type)、普通にslice,map,channelを意味する。

数字やArrayと比べ、参照型変数はより複雑な構造がある。メモリの割り当てに加えて、ポインタ、長さ、ハッシュ分散、データキューなどの一連のプロパティも初期化する必要がある。

関数newは、指定された型の長さに従ってゼロ値のメモリを割り当て、ポインタを返す。型の内部構造と初期化メソッドはしない。 
参照型変数は、make関数を使用して作成する必要があり、コンパイラーは, makeをターゲット関数型変換の作成関数または命令に変換して、メモリ割り当てと関連するプロパティの初期化を正しく完成させる。

```go
package main

func mkslince() []int {
	s := make([]int, 0, 10)
	s = append(s, 100)

	return s
}

func mkmap() map[string]int {
	m := make(map[string]int)
	m["a"] = 1
	return m
}
func main() {
	m := mkmap()
	println(m["a"])

	s := mkslince()
	println(s[0])
}

```

もちろん、関数newは参照型にメモリを割り当てることもできるが、この作成は不完全である。

```go
package main

import "fmt"

func main() {
	p := new(map[string]int) //関数new、ポインタを返す
	m := *p

	m["a"] = 1     //エラー　　panic: assignment to entry in nil map
	fmt.Println(m)
}
```


###1.6 型変換

暗黙的型変換によって引き起こされる問題は、それがもたらすメリットよりもはるかに大きい。
定数、別名型、と無名型以外、golangでは、明示的型変換は必須である。

```go
	a := 10
	b := byte(a)
	c := a + int(b)  //混合型表現は型の一貫性を保つ必要がある
```

変換のオブジェクトがポインタ、一方向チャネル、または戻り値のない関数型の場合は、構文分解エラーを避けるために括弧を使用する必要がある。

```go

func main() {
	x:=100
	p:=*int(&x) //エラー  cannot convert &x (type *int) to type int
	println(p)
}
```

括弧を使ってポインタ型だと解析させるのが正しいやり方である。

```  
(*int)(p)            ⇒括弧なければ⇒　　*(int(p))
(<-chan int)(c)      ⇒括弧なければ⇒    <-(chan int(c))
(func())(x)          ⇒括弧なければ⇒    func()x
func()int(x)         ⇒括弧なければ⇒   (func()int)(x)
```
最後の例だが、返す値がある関数では、括弧を省略できるが、使用すれば、読みやすくなる。

###1.7 ユーザ定義型

キーワードtypeを使用すれば、ユーザ定義型を定義できる。

```go
package main

import "fmt"

type flags byte

const (
	read flags = 1 << iota
	write
	exec
)

func main() {
	f := read | exec
	fmt.Printf("%b\n", f)
}
```

varやtypeと類似、いくつかのtypeをクループに構成し、関数やコードブロック内にローカル変数を定義する。

```go
package main

import "fmt"

func main() {
	type (
		user struct {
			name string
			age  uint8
		}
		event func(string) bool
	)

	u := user{"Zhang", 20}
	fmt.Println(u)

	var f event = func(s string) bool {
		println(s)
		return s != ""
	}
	f("abc")
}
```

基礎型が指定されていても、それは、それらが同じ基礎型とデータ構造を持っていることを示すだけであり、2つの間には関係がなく、全く異なる型に属していることを示している。

```go

package main

func main() {
	type data int
	var d data = 10

	var x int = d  //エラー:cannot use d (type data) as type int in assignment
	println(x)

	println(d == x)　//エラー:　invalid operation: d == x (mismatched types data and int)
}
```

T
###1.8 無名型

bool, int, string などの型が明示的な識別子を持つのに対して、array, slice, dictionary, channel などの型は、特定の要素の型や長さなどのプロパティに関連しているため、無名型(unnamed type)と呼ばれている。もちろん、typeを使って、具体的な名称を与え、夏名付け型(named type)に変換する。

同じステートメントを持つ無名型は、同じ型として扱われる。
・同じ基底型のポインタ
・同じ要素の型と長さの配列(array)
・同じ要素タイプのスライス(slice)
・同じkey-valueタイプのマップ(map)
・同じデータタイプと動作方向のチャンネル(channel)
・同じフィールド名、フィールド型、ラベル、フィールド順序のコンストラクト(struct)
・同じ引数と戻り値のリスト(パラメータ名は含まない)の関数 (func)
・同じメソッド名、メソッドシグネチャ（順序を含まない）を持つインターフェース(interface)


　　　　　　　　　　　　　　　　　　　　　　　　　　　　　

[GO言語学習ノート#1　　変数型(1)](http://qiita.com)