1. go 语言左括号必须和函数名同行
2. 程序必须有一个 main 包才可以运行
【注意:liteide 图形化开发环境下,一个文件夹下只能有一个 main 函数】
使用命令行编译时,可以只针对文件编译,即使一个文件夹下两个文件都带 main 函数,互不干扰
go build xxx.go
3. 数据类型作用:告诉编译器使用多大内存存储
4. 变量命名规则同 Java 相同
5. 变量声明 :
var a int (此时 a 为 0,默认初始化为 0)
var b int = 10 (直接初始化)
var a = 0 (自动推导类型)
a := 0 (函数内可以使用,极简写法)
a , b := 1 , 2 (多重赋值)
6. Println 与 Printf 的区别
Println 一段一段输出,Printf 格式化输出
7. 使用匿名变量丢弃数据: _ , a = i , j
8. 常量
const a int = 10
const a = 10 (自动推导类型)
9. 块变量声明
var (
a int
b float64
)
10. 枚举,自动加 1,遇到 const 充值为 0,同一行值相同
const (
a = iota // a = 0
b // b = 1 (iota 可以省略)
c,e = iota , iota // c = e = 2
)const d = iota // d 为 0
11. 浮点数默认推导为 float64 类型
12. byte 对应 uint8(存英文),rune 对应 uint32 (存中文 Unicode)【计算机只能存数,不能存字符】
13. go 语言的字符串类型 string,注意小写,跟 java 不同
14. 使用 len(中文字符串)时需要特别注意,如 len("中国") == 6,而不是 2,len(空串) == 0 ,自动忽略了 \0
15. %v 格式化,自动匹配类型格式
16. 输入类似 C 语言, fmt.Scanf("%d", &a),简单版 fmt.Scan(&a)
17. 类型别名 type xxx int32 , xxx 就代表 int32
18. go 的 取地址(&)与取值(*)类似于 C 语言
19. if 支持一个简单语句,使用分号分隔
20. go 语言的 switch case 自动 break,想要继续执行使用 fallthrough,switch 支持一个简单句
switch 可以支持条件判断
var a = 5
switch {
case a > 10:
xxxx
}
21. 循环简单化,就是 for,go 语言有 python 的 range [ for i,v := range xxx ]
22. go 语言 有 goto ,不能跨函数,goto 标签
23. go 语言函数无需提前声明,直接定义函数体在任何地方都可以,顺序无关,类似于 Java
24. 函数格式
func 函数名( xx int, xxx string) (a int, b string) {
......
a , b = 1 , 2
return
}
注意,返回值也可以直接声明名字变量,直接 return 就可以,一个返回值,可以省略括号
既声明返回值名称,return 也写了返回值,以 return 为准
有返回值的函数不能省略 return 关键字
返回值不能有命名的有不命名的,需要统一
25. 不定长参数,类似 java,放形参最后
(args ...int)
for _, v := range args {
}
26. 不定长参数传递,需要带着 ...
func f1(args ...int){
f2(args...)
f3(args[:2]...)
}
27. 函数类型,(函数可以赋值给函数类型变量,从而进行传递)
type FuncType func(int,int) int // 定义一种函数类型
var f1 FuncType = Add // 定义一个函数变量 f1,并把 Add 函数赋给它,Add 函数格式与 FuncType 一致
28. 匿名函数和闭包
f1 := func(){
这里能捕获到 f1 所在作用域的变量
}
f1()
type FuncType func()
var f2 FuncType = f1 // 可以将函数变量赋值给另一个函数变量
f2()
func(){
}() // 也可以不赋值,直接后边加小括号执行
29. 闭包内引用外部变量,修改后,外部变量也就改了
30. 返回值是匿名函数,匿名函数使用的外部变量不释放,不再二次初始化(闭包的特点)
func f1() func() int {
var x int
return func() int{
x ++
return x * x
}
}
fTest := f1()
fTest() // 1
fTest() // 4 x 不会重新初始化为 0
31. defer 栈试调用,发生异常也会调用
32. golang os.Args 第一个参数是程序自身 (同 python, sys.argv[0];同 shell,$0 是文件名)
java args 第一个参数就是实际参数,与其他三种语言不同
即 golang 、 python、shell 的参数向量都包含文件名,而 java 不包含
33. 变量使用作用域,就近原则
34. 同一个目录下,包名一样,否则编译失败
35. 同一个目录,函数直接调用,(不分你我)
36. 函数名大写开头,才能供其它包调用,包名.函数(),否则找不到函数
37. init 导入时执行
func init() {
}
38. GOBIN 指明 bin 目录位置,默认 位于 GOPATH 下
39. new 函数,如 var p *int = new(int) ,申请一块空间,返回地址,赋值给 *int,(空间能自动回收)
40. 数组: var arr [50]int,方括号里需要常量(跟 C 语言一样)
使用 {} 初始化 arr := [4]int{1,2,3,4},部分初始化时其余的赋值0
41. golang 数组能直接比较是否相等(判断每个元素是否相等),数组支持直接赋值
42. 随机数的种子不变,每次运行产生的随机数就固定,可以使用时间作为种子
43. 冒泡排序复习
for i := 0; i< n-1 ;i++ {
for j := 0; j < n-1-i; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
44. 数组作函数参数 ==》 值传递(数组会被拷贝),跟 C 语言不同,
数组作参数可以指明大小,fun1(arr [5]int)
只有明确传递数组指针,才是引用传递, func modify( p *[5]int)
45. 切片不用指定大小,比如 s := []int{} , s = append(s,3) 末尾追加元素
可以使用 make 创建切片,如 s := make([]int,5,10) ,长度为5,容量为10
如果不指定容量,容量就和长度保持一致
46. 使用数组构造的切片,底层存储依然是原数组,改变切片中元素的值相当于改变了原来的数组
47. 切片 append 容量不够时会自动扩容,以2倍容量扩容
48. 切片拷贝,使用 copy(dst,src)
49. 切片作为参数,是引用传递
50. map ==> var m1 map[int]string ; m2 := make(map[int]string) ; m3 := make(map[int]string,10) 预分配10个大小容量
51. map 只有 len ,没有 cap 操作
52. map 初始化 m := map[int]string{1:"hello"}
53. map 的迭代
for key, value := range m {
}
54. 判断 key 是否存在
value, ok := m[key]
55. 从 map 删除 key
delete(m,key)
56. map 作函数参数是引用传递
57. 结构体,内部变量不用 var
type Student struct {
id int
name string
}
var s1 Student = Student{1,"xiaoming"} //顺序初始化
s2 := Student{id:1} // 部分成员初始化,其他初始化为0
p1 := &Student{1,"xiaoming"} // 结构体指针
var s Student
s.id = 1
58. 通过指针操作成员,p.id 和 (*p).id 完全等价
59. 通过 new 申请一个结构体(指针)
p := new(Student)
60. 面向对象
封装 : 方法
继承 : 匿名字段
多态 : 借口
61. 匿名字段:结构体成员只有类型
type Student struct {
Person // 匿名字段,相当于把 Person 成员放在这里
class string
}
62. 带匿名字段的结构体初始化
s := Student{ Person{ xxx }, xxx }
s := Student{ Person: Person{name:"mike"}}
63. 同名字段,默认就近原则,如果需要使用匿名字段的属性,需要显示指明
m.Person.name
64. 方法接收者类型本身不能是指针
65. 只要接收者不同,方法同名也属于不同方法,不会冲突
66. 当接收者是值时,实际是一份拷贝,对其修改不影响原值,引用传递才能同步修改
67. 匿名字段,方法同样继承过来
68. 方法值可以赋值给变量,如 pFun := p.PrintInfo pFun()
69. 方法表达式, pFun := (*Person).PrintInfo pFun(&person)
70. 接口定义
type xxx interface {
xxx()
}
71. 只要实现了接口的所有方法,就可以把该类型变量(接收者类型)赋值给该接口变量
72. 错误异常,fmt.Errorf() , errors.New() 两种方式返回的都是 error 对象
73. 显示中断程序,panic("xxx")
74. defer recover 恢复 panic ,
defer func(){
if err := recover(); err != nil {
fmt.Println(err)
}
}()
75. 字符串常见操作
import "strings"
strings.Containers(原串,字串)
strings.Join(字符串数组,",")
strings.Index(原串,字串)
strings.Split(原串,分隔符)
strings.Trim(原串," ")
strconv.FormatXXX(XXX),转为字符串
strconv.ParseXXX(XXX),字符串转其他类型
r := regexp.MustCompile(`xxx`) 编译正则
76. 处理 json ( "encoding/json")
buf, err := json.Marshal(结构体) // 通过结构体生成 json
buf, err := json.MarshalIndent(结构体,""," ") // 格式化
type A {
Company string `json:"company"` 重命名
Name string `json:"-"` 不会输出
Ok bool `json:",string"` 转 string
}
json.UnMarshal(buf, &结构体) // 解码 json
77 . 取类型
data := value.(type)
78. 文件分类
设备文件:标准输出(屏幕),标准输入(键盘) os.Stdout os.Stdin