Go学习笔记-第1章
来源:互联网 发布:机顶盒检测软件 编辑:程序博客网 时间:2024/06/03 14:41
Go 学习笔记
第一章 类型
1.1 变量
Go 语言变量名由字母、数字、下划线组成,其中首个字母不能为数字。
Go 是静态类型语⾔,不能在运⾏期改变变量类型。
使⽤关键字 var 定义变量,⾃动初始化为零值。如果提供初始化值,可省略变量类型,由编译器⾃动推断。
var x int var y int = 1var radius float32 = 2.0var str = "Hello Go"
在函数内部,可⽤更简略的 “:=” ⽅式定义变量。
var func main(){ m:="abc"}
可以一次定义多个变量。
var x,y,z int //定义全局变量var m,n = "abc",123 var ( a int b float32)var func main(){ i := "Hello Go" //编译器会将未使⽤的局部变量当做错误=>i declared and not used。 println(x, n, b)}
注意重新赋值与定义新同名变量的区别。
var ( a int b float32)func main() { println(&a) m := "Hello Go" println(&m) m, n := "what?", 10 // 重新赋值: 与前 m 在同 层次的代码块中,且有新的变量被定义。 println(&m, n) a := 12 // 定义新同名变量: 不在同层次代码块。 println(&a)}
输出结果
0x10b29a80xc420039f680xc420039f68 100xc420039f60
1.2 常量
常量值必须是编译期可确定的数字、字符串、布尔值。
const x, y, z = 1, "Hello Go", false //多常量初始化const ( //常量组 m = false n = false i, j = "abc", 1 //类型自动判断)func main() { const x = 2//未使用局部常量不会引发编译错误}
在常量组中,如不提供类型和初始化值,那么视作与上 常量相同。
const ( //常量组 m = false n //n = false i = 10 j //j = 10)
常量值还可以是 len、cap、unsafe.Sizeof 等编译期可确定结果的函数返回值。
const ( x = "Hello Go" y = len(x) z = unsafe.Sizeof(x))
如果常量类型 以存储初始化值,那么不会引发溢出错误。
const ( x byte = 20 y int = 1e20//constant 100000000000000000000 overflows int)
枚举
关键字 iota 定义常量组中从 0 开始按 计数的 增枚举值。
const ( Sunday = iota //0 Monday //1 Tuesday //2 Wednesday //3 Thursday //4 Friday //5 Saturday //6)
const ( _ = iota // iota = 0 KB int64 = 1 << (10 * iota) // iota = 1 MB // 与 KB 表达式相同,但 iota = 2 等同于=> MB int64 = 1 << (10 * 2) GB TB)
在同 常量组中,可以提供多个 iota,它们各增 。
const ( A, B = iota, iota << 10 //0,0 << 10)
如果 iota 增被打断,须显式恢复。
const ( A = iota //1 B //2 C = "c" //c D //c E = iota //4 显式恢复。注意计数包含了 C、D 两行 。 F //5 G //6)
1.3 基本类型
支持八进制、 十六进制,以及科学记数法。标准库 math 定义了各数字类型取值范围。
a, b, c, d := 071, 0x1F, 1e9, math.MinInt16
空指针值 nil
1.4 引用类型
引 类型包括 slice、map 和 channel。它们有复杂的内部结构,除了申请内存外,还需
要初始化相关属性。
内置函数 new 计算类型 ,为其分配零值内存,返回指针。 make 会被编译器翻译 成具体的创建函数,由其分配内存和初始化成员结构,返回对象 指针。
number := []int{0, 0, 0}number[1] = 10x := make([]int, 3) // len = 3 slice.c: runtime·makeslicex[1] = 10y := new([]int)y[0] = 10 // Error: invalid operation: y[1] (index of type *[]int)
1.5 类型转换
不⽀持隐式类型转换,即便是从窄向宽转换也不⾏。
var x byte = 10//var m int = x //cannot use x (type byte) as type int in assignmenty := int(x)
同样不能将其他类型当 bool 值使⽤。
var x = 1if x {//non-bool x (type int) used as if condition println("true")}
1.6 字符串
字符串是不可变值类型,内部⽤指针指向 UTF-8 字节数组。
• 默认值是空字符串 “”。
• ⽤索引号访问某字节,如 s[i]。
• 不能⽤序号获取字节元素指针,&s[i] ⾮法。
• 不可变类型,⽆法修改字节数组。
• 字节数组尾部不包含 NULL。
// string is the set of all strings of 8-bit bytes, conventionally but not// necessarily representing UTF-8-encoded text. A string may be empty, but// not nil. Values of string type are immutable.type string string
使⽤索引号访问字符 (byte)。
var str = "Hello Goland"println(str[0] == 72, str[1], str[len(str)-1])
输出
true 101 100
连接跨⾏字符串时,”+” 必须在上⼀⾏末尾,否则导致编译错误。
var str = "Hello " + " Goland"s2 := "Hello, " + "World!" //invalid operation: + untyped stringprintln(str)println(s2)
⽀持⽤两个索引号返回⼦串。⼦串依然指向原字节数组,仅修改了指针和⻓度属性。
str := "Hello " + " Goland"str1 := str[1:] //ello Golandstr2 := str[:6] //Hello str3 := str[2:5] //lloprintln(str1)println(str2)println(str3)
单引号字符常量表⽰ Unicode Code Point,⽀持 \uFFFF、\U7FFFFFFF、\xFF 格式。
对应 rune(int32) 类型,UCS-4。
func main() { fmt.Printf("%T\n", 'a') var c1, c2 rune = '\u6211', '们' println(c1 == '我', string(c2) == "\xe4\xbb\xac")}
输出
int32true true
要修改字符串,可先将其转换成 []rune 或 []byte,完成后再转换为 string。⽆论哪种转
换,都会重新分配内存,并复制字节数组。
str := "Hello Goland"number := "110"s := []byte(str)phone := []rune(number)s[0] = 'F'phone[len(number)-1] = '9'println(string(s))println(string(phone))
输出
Fello Goland119
⽤ for 循环遍历字符串时,也有 byte 和 rune 两种⽅式。
str := "Hello"for i := 0; i < len(str); i++ { //byte fmt.Printf("str[%d] = %c \n", i, str[i])}for _, value := range str { //rune fmt.Printf("%c\n", value)}
输出
str[0] = H str[1] = e str[2] = l str[3] = l str[4] = o Hello
1.7 指针
⽀持指针类型 T,指针的指针 **T,以及包含包名前缀的 \
type User struct { name string}user := User{"小强"}userIp := &uservar ipStr *UseripStr = &userprintln(ipStr)println(userIp)fmt.Printf("name=%s\n", userIp.name)
输出
0xc420039f58name=小强0xc420039f58
不能对指针做加减法等运算。
number := 1234p := &numberp++ //invalid operation: p++ (non-numeric type *int)
可以在 unsafe.Pointer 和任意类型指针间进⾏转换。
x := 0x12345678p := unsafe.Pointer(&x) // *int -> Pointern := (*[4]byte)(p) // Pointer -> *[4]bytefor i := 0; i < len(n); i++ { fmt.Printf("%X ", n[i])}
输出
78 56 34 12 0xc420039f48
返回局部变量指针是安全的,编译器会根据需要将其分配在 GC Heap 上。
func test() *int { x := 100 return &x // 在堆上分配 x 内存。但在内联时,也可能直接分配在目标栈。}
将 Pointer 转换成 uintptr,可变相实现指针运算。
func main() { d := struct { s string x int }{"abc", 100} p := uintptr(unsafe.Pointer(&d)) // *struct -> Pointer -> uintptr p += unsafe.Offsetof(d.x) // uintptr + offset p2 := unsafe.Pointer(p) // uintptr -> Pointer px := (*int)(p2) // Pointer -> *int *px = 200 // d.x = 200 fmt.Printf("%#v\n", d)}
输出
struct { s string; x int }{s:"abc", x:200}
注意:GC 把 uintptr 当成普通整数对象,它⽆法阻⽌ “关联” 对象被回收。
- Go学习笔记-第1章
- Go语言探索第一天,学习笔记
- Go语言学习笔记1
- Go语言学习笔记1
- 《GO学习笔记》------------------------(1)
- go学习笔记(1)
- 【Go学习笔记】Hello Go!
- 第1章学习笔记
- Go语言学习笔记1/2
- Go语言基础语法学习笔记[1]
- Go语言学习笔记 -- 函数(1)
- go语言学习笔记(1) 环境搭建
- go lang学习笔记(1)
- Go语言学习笔记
- Go学习笔记
- go学习笔记
- Go语言学习笔记
- go语言学习笔记
- G
- vue移动端flexible.js结合Muse-ui使用的小坑
- linux /proc文件系统_seq_file
- Android 如何快速写满存储空间
- LeetCode#7-Reverse Integer
- Go学习笔记-第1章
- 各个历史版本 cuda toolkit 下载链接
- #和##操作符使用分析
- Go基础
- Mac “'chromedriver' executable needs to be in PATH”
- 基于PCL的三维重建——点云的滤波处理
- Git教程
- github常用小记
- Git基本命令总结