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()裏又重新調用自身,陷入無限遞歸,然後棧溢出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章