Go语言基础回顾

105 阅读2分钟

本节重点

  • goland设置git终端
  • go的install命令
  • 内存逃逸
  • 接口与类型断言
  • 多态
  • return、exit、Goexit之间的区别

内容详解

goland设置git终端

setting-->tools-->terminal-->shell path设置为你下载git的文件夹bin目录下的bash.exe

image.png

go常用命令(build/run/install/env)

go env:查看go的环境变量。

go install:编译生成的exe文件无法在别的目录运行,如何解决这个问题呢?使用go install命令将exe文件保存到GOPATH下的bin目录中,即GOBIN中,将GOBIN配置进系统变量就可以在任意目录下运行这个exe文件了。

内存逃逸

 go语言声明一个变量,会自动将其放到堆上或者栈上,如果是临时变量就会放到栈上,如果不能随便释放的变量就会放到堆上。这个分配过程在编译的时候就确定了。

 看下面这个程序

func main() {
   fmt.Println(*testPtr())
}

func testPtr() *string {
   city := "上海"
   ptr := &city
   return ptr
}

 这个程序能否正常打印city?答案是可以的。如果是c语言,当函数结束时,内存就会被销毁,其city变量也会被清空。而go语言则不会,因为go把city变量存放在了堆空间中,堆空间中的变量不会随着函数的结束而销毁。

 那么如何更清晰的看到它是在堆上还是栈上?通过编译器查看。

$ go build -o test.exe --gcflags "-m -m -l" main.go

也可以用重定向打印到文件中:

$ go build -o test.exe --gcflags "-m -m -l" main.go >1.txt 2>&1

然后用greap更清楚的查看: $ grep -E "name|city" 1.txt --color

image.png 可以看到city逃逸了而name没有逃逸。

接口与类型断言

array := make([]interface{}, 3)
array[0] = 1
array[1] = "Hello"
array[2] = true

for _, value := range array {
   switch v := value.(type) {
   case int:
      fmt.Printf("当前类型为int,内容为:%d\n", v)
   case string:
      fmt.Printf("当前类型为string,内容为:%s\n", v)
   case bool:
      fmt.Printf("当前类型为bool,内容为:%v\n", v)
   default:
      fmt.Println("不识别当前类型")
   }

多态

 Go语言的多态的实现不需要父子类关系,只需要实现同一个接口的所有方法即可。

 下面的程序中,Student和Teacher都实现了People接口,因此可以声明一个People接口的变量,指向Student和Teacher的对象。

type People interface {
   printAge()
}

type Student struct {
   age int
}

func (s *Student) printAge() {
   fmt.Println("Student age is :", s.age)
}

type Teacher struct {
   age int
}

func (t *Teacher) printAge() {
   fmt.Println("Teacher age is :", t.age)
}

func doPrint(p People) {
   p.printAge()
}

func main() {
   var people People
   student := Student{
      11,
   }
   teacher := Teacher{
      25,
   }
   people = &student
   people.printAge()

   people = &teacher
   people.printAge()

   doPrint(&student)
   doPrint(&teacher)
}

return、exit、Goexit之间的区别

  • return :退出当前函数
  • exit :退出当前进程
  • Goexit :退出当前go程
go func(){
go func() {
   func(){
      fmt.Println("这是子go程内部的函数")
      //return
      //os.Exit(-1)
      //runtime.Goexit()
   }()
   fmt.Println("子go程结束")
}()
time.Sleep(2*time.Second)
fmt.Println("这是最外层go程")
}()

fmt.Println("这是主go程")
time.Sleep(3*time.Second)
fmt.Println("OVER")