知识补充

堆和栈区别
堆动态分配内存先进后出栈

java的数据类型都在堆中。go语言可以在堆可以在栈。

函数返回指针

runtime
package main

import "fmt"

func test() *int {
    var inner int = 100
    return &inner
}

func main() {
    outer := test()
    fmt.Println(outer)
}

理解指针

golang中,指针是一种类型,指向变量所在的内存单元(不是内存地址)。
申明: 在变量名前加上星号字符,比如 *age ,指向变量age所在的内存单元

&(取址符): 对变量取址
&age
*(表示声明指针) :或者对指针取值
*age**agex *int*x

package main

import (
   "fmt"
   "reflect"
)

func main(){
   k:=40
   fmt.Println(k)
   fmt.Println(say("hello,world","lf"))
   fmt.Println(reflect.TypeOf(k))  //检查变量类型
   
   // 获取变量在计算机内存中的地址,可在变量名前面加上&字符。
   fmt.Println(&k) 
   
   // &k 引用的是变量k的值所在的内存地址
   showMemoryAddress(&k)  //返回的地址是相同的
}

// *int参数类型位指向整数的指针,而不是整数
func showMemoryAddress(x *int){ 
	// 本身就是指针,打印地址不需要 & 这个符号,如果想使用指针指向的变量的值,而不是其内存地址,可在指针变量前面加上星号
   fmt.Println(*x)  
   return
}

func say(param,tt string) string{
   return param+"--"+tt
}

类型断言

我们看一个例子:

package main

import (
	"encoding/json"
	"fmt"
	"log"
)

var json_str=`{"code":1001,"student":{"name":"tom","age":18}}`


// json to map
func main() {
	 var p  map[string]interface{}
	 err:=json.Unmarshal([]byte(json_str),&p)
	 if err !=nil{
	 	log.Fatal(err)
	 }
	fmt.Print(p)
	fmt.Print("\n")
	fmt.Println(p["code"])
	 fmt.Println(p["student"])
	 //  此时拿student下的key值不能直接像上面一样,需要下面这样
	 var res = p["student"]
	 fmt.Printf("%T",res)
	 fmt.Print("\n")
	 // 断言取值
	last_res:=p["student"].(map[string]interface{})["age"]
	fmt.Print(last_res)

}
x.(T)

看官方的解释:

For an expression x of interface type and a type T, the primary expression x.(T) asserts that x is not nil and that the value stored in x is of type T.

map[string]interface{}
type Point struct {
    Name string
    X, Y int
}

func main() {
    in := `{"Name":"center","X":2,"Y":3}`

    pt := Point{}
    json.Unmarshal([]byte(in), &pt)

    fmt.Printf("Result: %+v", pt)
}