golang疑难点记录

本文记录了Go语言中的一些关键概念,包括堆栈的区别,函数如何返回指针,理解指针的用法,特别是Go中的&(取址符)和*(表示声明指针),以及如何进行类型断言。通过实例解析了Go语言中指针的声明和使用,以及类型断言在处理JSON数据时的重要性。
知识补充
堆和栈区别

是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。
堆是指程序运行是申请的动态内存,而栈只是指一种使用堆的方法即先进后出
先进后出:就像放在箱子里的衣服,先放进去的后出来。
是先进后出的,但是于堆而言却没有这个特性,两者都是存放临时数据的地方。 对于堆,我们可以随心所欲的进行增加变量和删除变量,不要遵循什么次序,只要你喜欢。

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)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叱咤少帅(少帅)

如果文章对你有帮助就打赏下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值