一、第一个程序

1.代码示例

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main(){
  6. fmt.Println("hello world")
  7. }

2.手动执行
go run xx.go
3.编译为可执行程序
go build -o xx.exe xx.go
4.代码格式调整
idea:Ctrl+Alt+L
命令行: gofmt -w xxx.go

注意:如果在windows开发后需要打包成在linux可执行程序每次都需执行以下三步
set ENABLECGO=0 //该配置不是必须,请根据实际配置
set GOARCH=amd64
set GOOS=linux
go build -o xxx xx.go

二、语法要求

1.命名规范
1) package 名称要与文件名相同
2) 变量、函数名 严格区分大小写,首字母大写为公有(public),小写为私有(private)
3) _表示省略返回值

2.变量定义

  1. //局部变量定义必须被引用,否则程序会报错
  2. var a = 1
  3. var c int = 1
  4. //:只可定义局部变量,不可定义全局
  5. b := 1
  6. //批量定义
  7. var (
  8. d = 1
  9. f = 1
  10. )
  11. //常量定义,不可被改变
  12. const FIRST_NUM = 1
  13. //const结合iota
  14. const (
  15. //iota默认为0,SECOND_NUM值为0
  16. SECOND_NUM = iota
  17. //定义iota后,下面的变量可不主动赋值,默认会根据iota+=1进行赋值,THREE_NUM值为1
  18. THREE_NUM
  19. //这里iota会遵从iota+=1的原则变为2,然后乘以10,最后赋值为20
  20. FOUR_NUM = iota * 10
  21. /*这里iota的值增长规则不变,还是iota+=1,这里iota值为3,由于上一步附加了*10的规则,
  22. 这里FIVE_NUM值为30*/
  23. FIVE_NUM
  24. )

3.变量转换

  1. package main
  2. import (
  3. "fmt"
  4. "strconv"
  5. )
  6. func main(){
  7. //类型转换需要进行显示的转换
  8. var i = 100
  9. var fi = float32(i)
  10. fmt.Println(fi)
  11. fmt.Printf("fi的类型为:%T",fi)
  12. fmt.Println()
  13. //int转字符串,参数一表示要转换的值,参数2表示转换的结果为几进制
  14. var strNum = strconv.FormatInt(10,10)
  15. fmt.Println(strNum)
  16. fmt.Printf("strNum的类型为:%T",strNum)
  17. fmt.Println()
  18. //字符转转int,参数一为要转换的值,参数二为转换的结果为几进制,
  19. //参数三bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64
  20. var intNum, _ = strconv.ParseInt(strNum,2,0)
  21. fmt.Println(intNum)
  22. fmt.Printf("strNum的类型为:%T",intNum)
  23. fmt.Println()
  24. }

4.指针

  1. package main
  2. import "fmt"
  3. func changeValue1(p *int) {
  4. //*p 指向地址存储的值
  5. *p = 10
  6. }
  7. func changeValue2(p int) {
  8. //p为局部变量,会创建新的地址
  9. p = 100
  10. }
  11. func main() {
  12. var a = 1
  13. //&a 获取a变量的指针地址
  14. changeValue1(&a)
  15. changeValue2(a)
  16. fmt.Println(a) //最终结果为10
  17. //指针类型的变量同样有地址,因此出现多重指针
  18. var pp = **int
  19. var p = &a
  20. pp = &p
  21. }
  22. //make和new的区别
  23. //make和new都是用来申请内存的
  24. //make是给map、slice、chan进行内存申请的,返回的是对象本身。
  25. //new是给string、int等基本数据类型进行内存申请的,返回的是对应的指针类型,很少用

5.函数返回值

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. //无参数返回
  6. func foo1(var1 int,var2 string) {
  7. fmt.Println("----foo1----")
  8. fmt.Println(var1,var2)
  9. }
  10. //返回一个参数
  11. func foo2(var1 int,var2 string) int {
  12. fmt.Println("----foo2----")
  13. fmt.Println(var2)
  14. return var1
  15. }
  16. //返回多个参数
  17. func foo3(var1 int,var2 string) (int,string) {
  18. fmt.Println("----foo3----")
  19. return var1,var2
  20. }
  21. //返回多个同类型参数,并对参数命名
  22. func foo4(var1,var2 int) (r1,r2 int) {
  23. fmt.Println("----foo4----")
  24. fmt.Println("r1=",r1,",r2=",r2)
  25. //当给返回参数命名后,该返回结果会默认为整个函数的局部变量,并赋予默认值.
  26. //若返回参数命名后可直接使用 return r1,r2,也可直接return
  27. return var1,var2
  28. }
  29. func main(){
  30. foo1(100,"无参数返回")
  31. foo2Num := foo2(100,"返回一个参数")
  32. fmt.Println(foo2Num)
  33. foo3Num, foo3Str := foo3(100, "返回多个参数")
  34. fmt.Println(foo3Num, foo3Str)
  35. foo4Num1, foo4Num2 := foo4(1,2)
  36. fmt.Println(foo4Num1, foo4Num2)
  37. //_表示丢弃返回结果,直接垃圾回收
  38. _,_ = foo4(1,2)
  39. }

6.init函数和import的导包流程
import->const->var->init->main
image.png
7.import 导包

  1. package main
  2. //两个包不可相互依赖,例如:
  3. //A依赖B,B依赖A,如果出现该情况会报import cycle not allowed的错误
  4. import (
  5. //正常导包
  6. "fmt"
  7. //匿名导包,只会默认调用包内的init函数,其他函数无法调用
  8. _ "xxx"
  9. //别名导包,可以使用别名进行保内的函数调用
  10. mylib "xxx"
  11. //本地导包,无需使用别名,直接使用函数名即可调用保内函数
  12. . "xxxx"
  13. )

8.defer关键字 (最后执行)

  1. package main
  2. import "fmt"
  3. func return1() int {
  4. fmt.Println("--------return 1----------")
  5. return 1
  6. }
  7. func return2() int {
  8. fmt.Println("--------return 2----------")
  9. return 2
  10. }
  11. func execReturn() int {
  12. defer return1()
  13. //这里return 分为执行函数,返回结果两部,defer语句在这两步中间执行
  14. return return2()
  15. }
  16. func main() {
  17. defer fmt.Println("defer表示该语句最后执行,我相当于java的finally")
  18. defer fmt.Println("我是第二个defer,defer是先进后出,因此我不能最后打印")
  19. fmt.Println("我想最后执行")
  20. fmt.Println(execReturn())
  21. }

9.数组以及slice(动态数组)

  1. package main
  2. import "fmt"
  3. //数组,值传递无法修改原数组的值
  4. func printArray1(array [4]int) {
  5. fmt.Println("普通数组")
  6. for index, value := range array {
  7. fmt.Println("index=", index, "value=", value)
  8. }
  9. }
  10. //slice(动态数组),引用传递
  11. func printArray2(array []int) {
  12. fmt.Println("slice-动态数组")
  13. for index, value := range array {
  14. fmt.Println("index=", index, "value=", value)
  15. }
  16. array[1]=1000
  17. }
  18. func main() {
  19. //定义数组
  20. var array1 [4]int
  21. var array2 = [4]int{1, 2, 3, 4}
  22. var array3 = []int{1, 2, 3, 4}
  23. printArray1(array1)
  24. printArray1(array2)
  25. printArray2(array3)
  26. fmt.Println("slice可以在函数中修改值")
  27. for index, value := range array3 {
  28. fmt.Println("index=", index, "value=", value)
  29. }
  30. }

10.slice是使用注意事项

  1. package main
  2. import "fmt"
  3. func printArray(array []int) {
  4. fmt.Println("-------------分割线------------")
  5. for index, value := range array {
  6. fmt.Println("index=", index, "value=", value)
  7. }
  8. }
  9. func main() {
  10. //slice声明的方式
  11. //方式一:声明一个slice,并非配两个空间,值为1,2
  12. array1 := []int{1, 2}
  13. printArray(array1)
  14. //方式二:声明一个slice,未分配空间,通过append分配空间并增加数值,默认值为nil
  15. var array2 []int
  16. printArray(array2)
  17. //方式三:通过make创建一个slice为slice分配指定大小空间,并设置初始扩容的cap值为10
  18. //如果不传入cap,初始cap与len相同
  19. //当len的大小超过cap时,cap会进行2倍扩容,当cap的数字大于1024后每次扩容以1.25倍进行扩容
  20. var array3 = make([]int, 1, 10)
  21. printArray(array3)
  22. if array3 == nil {
  23. fmt.Println("slice为nil")
  24. } else if len(array3) == 10 {
  25. fmt.Println("slice长度为10")
  26. } else {
  27. fmt.Println("slice不为nil")
  28. }
  29. //slice的使用
  30. //slice截取数组
  31. array4 := make([]int, 0)
  32. //追加数组元素
  33. array4 = append(array4, 1)
  34. array4 = append(array4, 2)
  35. array4 = append(array4, 3)
  36. array4 = append(array4, 4)
  37. //删除数组元素,表示将下标为1的元素删除,然后用下表为2的元素进1
  38. array4 = append(array4[:1], array4[2:]...)
  39. fmt.Println(len(array4))
  40. printArray(array4)
  41. //通过截取数组进行赋值,传递的是值引用,不是值,这里与python的规则不同,python传递的是值
  42. //如果想要值传递需要使用copy函数
  43. //在截取数据时,会以cap的数量为限定进行截取,比如len为3,cap为6你可以截取6个元素而不是3个
  44. //在截取数据前当原数组未进行删除时,大于len元素默认会赋值为0
  45. //如果原数组有进行删除,大于len的元素会以原数组未删除前下标的元素进行赋值不在为0
  46. fmt.Println(len(array4),cap(array4),&array4)
  47. array5 := array4[0:4]
  48. fmt.Println(len(array5),cap(array5),&array5)
  49. array5[0] = 100
  50. printArray(array4)
  51. printArray(array5)
  52. var array6 = make([]int,3)
  53. //通过copy进行slice深拷贝时,array6必须已分配等同的空间,否则会报错
  54. copy(array6, array4)
  55. array6[1] = 200
  56. printArray(array6)
  57. }

11.map使用

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. //遍历
  6. func printMap(myMap map[string]string) {
  7. for key, value := range myMap {
  8. fmt.Println("key=", key, ",value=", value)
  9. }
  10. }
  11. //删除
  12. func deleteMap(myMap map[string]string, key string) {
  13. delete(myMap, key)
  14. }
  15. //新增
  16. func addMap(myMap map[string]string, key string, value string) {
  17. myMap[key] = value
  18. }
  19. //修改
  20. func updateMap(myMap map[string]string, key string, value string) {
  21. myMap[key] = value
  22. }
  23. func main() {
  24. //map的声明方式
  25. //方式一
  26. var map1 map[string]string
  27. if map1 == nil {
  28. fmt.Println("map为空")
  29. }
  30. //方式二
  31. map2 := make(map[string]string, 10)
  32. map2["one"] = "first"
  33. //方式三
  34. map3 := map[string]string{
  35. "one": "first",
  36. "two": "second",
  37. }
  38. deleteMap(map3,"one")
  39. printMap(map1)
  40. printMap(map2)
  41. printMap(map3)
  42. }

12.struct(结构体)

  1. package main
  2. import "fmt"
  3. // User 自定义结构体
  4. type User struct {
  5. name string
  6. age int
  7. }
  8. //结构提函数传递为值传递,因此需要设置指针专递才可修改结构体属性
  9. func changeUser(user *User) {
  10. user.age = 100
  11. }
  12. //类比于上方法,区别在于该方法属于struct结构体的方法,结构液体传递在这里同意规范使用指针传递
  13. //如果值传递,方法内对该结构体值进行修改不可同步至方法外边指针
  14. func (u *User)ChangeUser(){
  15. u.age=10
  16. }
  17. func main() {
  18. //定义结构体方式
  19. //方式一
  20. var user User
  21. user.name = "名字"
  22. user.age = 24
  23. //方式二
  24. var user1 = User{name:"名字",age:24}
  25. //方式三
  26. var user2 = User{"名字",24}
  27. fmt.Println(user)
  28. fmt.Println(user1)
  29. fmt.Println(user2)
  30. changeUser(&user)
  31. fmt.Println(user)
  32. //匿名结构体定义
  33. var u struct{
  34. Name string
  35. }
  36. u.Name="222"
  37. fmt.Println(u)
  38. }

13.interface
interface更多使用,请参考面向对象多态

  1. package main
  2. import "fmt"
  3. //interface{}是万能数据类型
  4. func myFunc(arg interface{}) {
  5. fmt.Println("arg =", arg)
  6. //校验数据类型
  7. value, result := arg.(string)
  8. if result {
  9. fmt.Println("是字符串", value)
  10. } else {
  11. fmt.Println("不是字符串", value)
  12. }
  13. }
  14. func main() {
  15. myFunc(100)
  16. myFunc("string")
  17. }