知识补充
堆和栈区别
堆
是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存
,对其访问和对一般内存的访问没有区别。
堆是指程序运行是申请的动态内存,而栈只是指一种使用堆的方法即先进后出
。
先进后出:就像放在箱子里的衣服,先放进去的后出来。
栈
是先进后出的,但是于堆而言却没有这个特性,两者都是存放临时数据的地方。 对于堆,我们可以随心所欲的进行增加变量和删除变量,不要遵循什么次序,只要你喜欢。
java的数据类型都在堆中。go语言可以在堆可以在栈。
函数返回指针
go的函数可以直接返回局部变量的指针,这主要依赖go是有runtime
的语言,编译器在发现有变量可以逃逸出去的时候会在堆上分配变量而不是栈上,这样就可以返回该变量的指针了,且会使该地址的引用+1,当生命空间结束时,gc会去回收
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
所在内存地址,一般地址是十六进制。
*(表示声明指针) :或者对指针取值
声明指针*age
, 打印指针内存单元的值。**age
如下面x *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)
被称为 Type Assertion
看官方的解释:
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.
如果你不知道返回的json的数据类型,您必须使用通用 map[string]interface{}
类型来处理它。
如果您知道输入 JSON 的确切结构,您可以创建一个 struct以匹配预期的字段,这样做您可以将 JSON 文本解码为您自定义的值 struct类型,例如:
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)
}