golang 学习笔记 - 指针/成员方法调用/json字符串的构建与解析/String() string 栈溢出

本地的go文档(命令行启动):

godoc -http=:8090

浏览器访问 http://localhost:8090 即可,端口号可以随便替换未占用的。

`*` 和 `&` 的区别和用法

package main

import "fmt"

type Interger int

func main() {
	var a Interger = 1
	var b *Interger = &a
	fmt.Println(a)  // 1
	fmt.Println(&a) // 0xc4200885a8
	fmt.Println(b)  // 0xc4200885a8
	fmt.Println(*b) // 1
	fmt.Println(&b) // 0xc420098040
	fmt.Println(a == *b) // true
	fmt.Println(&a == b) // true
}

& 是取地址,& 会取到后面跟着变量的地址
* 是取指针值,如果 * 后面跟着指针,那么会取到指针所在的值,* 后面不能跟非指针变量。

成员方法的使用

package main

import "fmt"

type Interger int

func main() {
	var a Interger = 1
	var b Interger = 2
	var i interface{} = &a
	var j interface{} = a
	c := i.(*Interger).Add(b)
	d := j.(Interger).Add(b)
	fmt.Println(c)
	fmt.Println(d)
}

func (i Interger) Add(j Interger) Interger {
	return i + j
}

i 是 a 指针赋值, j 是 a 的赋值,两者都调用成员方法 Add(Interger)
go 会根据 func (i Interger) Add(j Interger) Interger
自动生成成员方法 func (i *Interger) Add(j Interger) Interger
反之,则不会。

json字符串的构建与解析

将json字符串解析为map的时候有些注意点,传入的是map的指针地址,map可以未初始化。

package main

func main() {
	str := `{"key":1, "value":2}`
	dataMap := make(map[string]int) // var dataMap map[string]int
	if err := json.Unmarshal([]byte(str), &dataMap); err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%v", dataMap)
}

json解析结构体,要注意结构内被解析的属性必须可以对外引用,即首字母大写。

package main

import (
	"encoding/json"
	"fmt"
)

type Describer struct {
	ass  int `json:"ass"` // 这里编译会通过,但是有一条警告:struct field ass has json tag but is not exported
	Ass2 int `json:"ass2"`
}

func main() {
	j := `{"ass":1, "ass2":2}`
	var d Describer
	if err := json.Unmarshal([]byte(j), &d); err != nil {
		println(err)
		return
	}
	println(fmt.Sprintln(d)) // {0, 2} 因为ass是小写没有,所以json.Unmarshal()里没法对其引用赋值。
}

String实现

fmt.Sprintf("%v", v)这个函数在将结构体转为字符串的时候,会调用结构体的 “String() string” 方法,你可以在新结构体中声明这个函数以改变输出结果,但是注意不当的操作会导致栈溢出。

package main

import (
	"fmt"
)

type Foo struct {
	Name string
}

func (f Foo) String() string {
	return fmt.Sprintf("%v", f)
}

func main() {
	f := Foo{"foo1"}
	println(f.String()) 
	// runtime: goroutine stack exceeds 1000000000-byte limit
	//fatal error: stack overflow
}

愿意正如介绍中所说,String()里又重新调用自身,陷入无限递归,然后栈溢出。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值