日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

《Go学习笔记 . 雨痕》类型

發布時間:2023/12/13 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 《Go学习笔记 . 雨痕》类型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、基本類型

清晰完備的預定義基礎類型,使得開發跨平臺應用時無須過多考慮符合和長度差異。

類型 長度 默認值 說明
bool 1 false
byte 1 0 uint8
int, uint 4, 8 0 默認整數類型,依據目標平臺,32 或 64 位
int8, uint8 1 0 -128 ~ 127,0 ~ 125
int16, uint16 2 0 -32,768 ~ 32,767,0 ~ 65,535
int32, uint32 4 0 -21億 ~ 21億,0 ~ 42億
int64, uint64 8 0
float32 4 0.0
float64 8 0.0 默認浮點數類型
complex64 8
complex128 16
rune 4 0 Unicode Code Point, int32
uintptr 4, 8 0 足以存儲指針的 uint
string "" 字符串,默認值為空字符串,而非 NULL
array 數組
struct 結構體
function nil 函數
interface nil 接口
map nil 字典,引用類型
slice nil 切片,引用類型
channel nil 通道,引用類型

支持八進制、十進制以及科學計數法。標準庫 math 定義了各數字類型的取值范圍。

import (
	"fmt"
	"math"
)

func main()  {
	a, b, c := 100, 0144, 0x64

	fmt.Println(a, b, c)
	fmt.Printf("0b%b, %#o, %#x
", a, a, a)

	fmt.Println(math.MinInt8, math.MaxInt8)
}

輸出:

100 100 100
0b1100100, 0144, 0x64

-128 127

標準庫 strconv 可在不同進制(字符串)間轉換。

import (
	"strconv"
)

func main()  {
	a, _ := strconv.ParseInt("1100100", 2, 32)
	b, _ := strconv.ParseInt("0144", 8, 32)
	c, _ := strconv.ParseInt("64", 16, 32)

	println(a, b, c)

	println("0b" + strconv.FormatInt(a, 2))
	println("0" + strconv.FormatInt(a, 8))
	println("0x" + strconv.FormatInt(a, 16))
}

輸出:

100 100 100
0b1100100
0144
0x64

使用浮點數時,須注意小數位的有效精度,相關細節可參考 IEEE-754 標準。

func main()  {
	var a float32 = 1.1234567899	// 注意:默認浮點數類型是 float64
	var b float32 = 1.12345678
	var c float32 = 1.123456781

	println(a, b, c)
	println(a == b, a == c)
	fmt.Printf("%v %v, %v
", a, b, c)
}

輸出:

+1.123457e+000 +1.123457e+000 +1.123457e+000
true true
1.1234568 1.1234568, 1.1234568

別名

在官方的語言規范中,專門提到 兩個 別名。

byte alias for unit8
rune alias for unit32

別名類型無須轉換,可直接賦值。

func test(x byte) {
	println(x)
}

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

	test(c)
}

但這并不表示,擁有相同底層結構的就屬于別名。就算在 64位 平臺上 int 和 int64 結構完全一致,也分屬不同類型,須顯式轉換。

func add(x, y int) int {
	return x + y
}

func main() {
	var x int = 100
	var y int64 = x		// 錯誤:cannot use x (type int) as type int64 in assignment

	add(x, y)			// 錯誤:cannot use y (type int64) as type int in argument to add
}

二、引用類型

所謂引用類型(reference type),特指 slice 、map 、channel 這三種預定義類型。相比 數字 、數組 等類型,引用類型 擁有更復雜的存儲結構。除分配內存外,他們還須初始化一系列屬性,諸如 指針 、長度 ,甚至包括哈希分布、數據隊列等。

內置函數 new() 按指定類型長度分配零值內存,返回指針,并不關心類型內部結構和初始化方式。而 引用類型 則必須使用 make() 函數創建,編譯器會將 make() 轉換為目標類型專用的創建函數(或指令),以確保完成全部內存分配和相關屬性初始化。

// test.go 文件

package main

func mkslice() []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 := mkslice()
	println(s[0])
}

輸出:

$ go build -gcflags "-l"  // 禁用函數內聯

$ go tool objdump -s "main.mk" test

TEXT main.mkslie(SB) test.go
    CALL runtime.makeslice(SB)

TEXT main.mkmap(SB) test.go
    CALL runtime.makemap(SB)    

除 new() / make() 函數外,也可用 初始化表達式,編譯器生成的指令基本相同。

當然,new() 函數也可為引用類型分配內存,但這是不完整創建。以字典(map)為例,它僅分配了字典類型本身(實際就是個指針包裝)所需內存,并沒有分配鍵值存儲內存,也沒有初始化散列桶等內部屬性,因此它無法正常工作。

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)
}

三、類型轉換

隱式轉換造成的問題遠大于它帶來的好處。

除 常量 、別名類型 以及 未命名類型 外,Go 強制要求使用顯示類型轉換。加上不支持操作符重載,所以我們總是能確定語句及表達式的明確含義。

func main() {
	a := 10
	b := byte(a)
	c := a + int(b) // 混合類型表達式必須確保類型一致
	fmt.Println(c)
}

同樣不能講 非bool 類型結果當作 true/false 使用。

func main() {
	x := 100

	var b bool = x // 報錯:cannot use x (type int) as type bool in assignment

	if x { // 報錯:non-bool x (type int) used as if condition
	}
}

語法歧義

如果轉換的目標 指針 、單向通道 或 沒有返回值的函數 類型,那么必須使用 括號(),以避免造成語法分解錯誤。

func main() {
	x := 100
	p := *int(&x)	// 報錯:cannot convert &x (type *int) to type int
					// invalid indirect of int(&x) (type int)
	println(p)
}

正確的做法是用括號,讓編譯器將 *int 解析為指針類型。

(*int)(p) --> 如果沒有括號 --> *(int(p))
(<-chan int)(c) <-(chan int(c))
(func())(x) func() x

func() int (x) --> 有返回值的函數類型可省略括號,但依然建議使用。
(func() int) (x) 使用括號后,更易閱讀

四、自定義類型

使用關鍵字 type 定義用戶自定義類型,包括基于現有基礎類型創建,或者是 結構體 、函數類型 等。

type flags byte

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

func main() {
	f := read | exec
	fmt.Printf("%b
", f)  // 輸出二進制標志位
}

輸出:

101

和 var 、const 類似,多個 type 定義可以合并成組,可在 函數 或 代碼塊內定義局部類型。

func main() {
	type (					// 組
		user struct {		// 結構體
			name string
			age  uint8
		}

		event func(string) bool // 函數類型
	)

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

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

	f("abc")
}

輸出:

{Tom 20}
abc

即便指定了基礎類型,也只表明它們有相同底層數據結構,兩者間不存在任何關系,屬完全不同的兩種類型。除操作符外,自定義類型不會繼承基礎類型的其他信息(包括方法)。不能視作別名,不能隱式轉換,不能直接用于比較表達式。

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

	var x int = d  // 錯誤:annot use d (type data) as type int in assignment
	println(x)

	println(d == x) // 錯誤:invalid operation: d == x (mismatched types data and int)
}

未命名類型

與有明確標識符的 bool 、int、string 等類型相比,數組 、切片 、字典 、通道 等類型與具體元素類型或長度等屬性有關,故稱作 未命名類型(unnamed type)。當然,可用 type 為其提供 具體名稱,將其改變為 命名類型(named type)。

具有相同聲明的未命名類型視作同一類型。

具有相同基類型的指針;
具有相同元素類型 和 長度的數組(array);
具有相同元素類型的切片(slice);
具有相同鍵值類型的字典(map);
具有相同數據類型及操作方向的通道(channel);
具有相同字段序列(字段名、字段類型、標簽,以及字段順序)的結構體(struct);
具有相同簽名(參數和返回值列表,不包括參數名)的函數(func);
具有相同方法集(方法名、方法簽名,不包括順序)的接口(interface);

容易被忽視的是 struct tag,它也屬于類型組成部分,而不僅僅是元數據描述。

func main() {
	var a struct { // 匿名結構類型
		x int `X`
		s string `S`
	}

	var b struct {
		x int
		s string
	}

	b = a // 錯誤:cannot use a (type struct { x int "X"; s string "S" }) as type struct { x int; s string } in assignment

	fmt.Println(b)
}

同樣,函數的參數順序也屬簽名組成部分。

func main() {
	var a func(int, string)
	var b func(string, int)

	b = a // 錯誤:cannot use a (type func(int, string)) as type func(string, int) in assignment

	b("s", 1)
}

未命名類型轉換規則:

所屬類型相同;
基礎類型相同,且其中一個是未命名類型
數據類型相同,將雙向通道賦值給單向通道,且其中一個為未命名類型;
將默認值 nil 賦值給 切片、字典、通道、指針、函數 或 接口;
對象實現了目標接口;

func main() {
	type data [2]int
	var d data = [2]int{1, 2} // 基礎類型相同,右值為 未命名類型

	fmt.Println(d)

	a := make(chan int, 2)
	var b chan<- int = a // 雙向通道 轉換為 單向通道,其中 b 為 未命名類型

	b <- 2
}

總結

以上是生活随笔為你收集整理的《Go学习笔记 . 雨痕》类型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜精品久久久久久久99 | 深夜福利免费视频 | 五月天黄色小说 | 亚洲AV成人午夜无码精品久久 | av在线电影观看 | 人人人人爽 | 日韩在线中文字幕视频 | 天天操天天草 | 国产精品66 | 国产chinesehd精品 | 日韩视频二区 | 亚洲av无码乱码国产精品fc2 | 黄色一级免费片 | 久久精品视频99 | 亚洲性片 | 久久综合婷婷国产二区高清 | 一本大道东京热无码 | 男生和女生一起搞鸡 | 免费看污的网站 | 国产成人精品一区二区三区视频 | 与子敌伦刺激对白播放的优点 | 天天操夜夜操 | 欧美日本在线视频 | 伊人www22综合色 | 欧美成人精品一区二区三区在线观看 | 欧美精品乱码久久久久久按摩 | 国产激情综合五月久久 | 国产日韩一区二区三免费高清 | 久久国产精品无码一区二区 | 美女被草 | 日本aa在线观看 | 精品国产xxx | 亚洲黄色精品 | 快色在线观看 | 日韩成人欧美 | 国产污污视频 | 欧美久久久久久久久中文字幕 | 国产午夜一区二区三区 | www.激情.com| 奇米视频在线观看 | 久久久线视频 10 | 久操av在线| 欧美偷拍精品 | av免费在线不卡 | 麻豆入口| 欧美激情网址 | 国色天香av | 日日干影院 | 中出视频在线观看 | 欧美h网站| 海角社区在线 | 一区二区三区视频在线播放 | 午夜久久网 | 国产成人看片 | 一区二区三区四区免费观看 | 欧美三级欧美一级 | 国产免费一区二区三区三州老师 | 免费黄色资源 | 国产欧美精品一区二区在线播放 | 一级黄色aa | 国产一线二线三线在线观看 | 国产日产欧洲无码视频 | 亚洲精品理论片 | 国产精品第一页在线观看 | 久久久久在线视频 | 求欧美精品网址 | 一二三区精品 | 亚洲乱码国产乱码精品 | 国产成人精品一区二区色戒 | 在线观看亚洲欧美 | 天天曰天天操 | 国产精品亚洲自拍 | 男女扒开双腿猛进入爽爽免费 | 国产色视频网站 | 99热免费精品 | 91av日本| 天天色综 | 亚洲色图狠狠干 | 国产成人精品免费看视频 | 黑人3p波多野结衣在线观看 | 日韩av在线免费 | 黄色不打码视频 | 国产尤物精品 | 美女久久久久久久久久 | avtt在线观看 | 亚洲综合图 | 老司机免费精品视频 | 露脸啪啪清纯大学生美女 | 黑人大群体交免费视频 | 99成人国产精品视频 | 朝桐光在线视频 | 国产亚洲精品久久久久四川人 | 超碰c | av在线免播放器 | 亚洲小说区图片区都市 | 亚洲免费视| 国模精品视频一区二区 | 国产又粗又长又爽 | 麻豆精品国产传媒av绿帽社 |