首頁 >後端開發 >Golang >golang不用指針可以嗎

golang不用指針可以嗎

(*-*)浩
(*-*)浩原創
2019-12-17 14:26:063462瀏覽

golang不用指針可以嗎

有時候看別人的go程式碼,發現他們有的在程式碼裡面用了指針,有的不使用。 (推薦學習:go

假設有個結構體類型叫做Person,發現有些方法會用func methodA (*person Person)作為參數,或是使用func *( person Person) methodA()作為結構體自己的方法,也就是person這個結構體可以直接呼叫methodA,但是用的是指標。

或是在map結構裡面看到var personMap map[string]*Person 的用法

如果是從java轉過來golang的話,可能不太懂。因為java的世界是沒有指標的,直接傳遞過去就可以用了,但是到golang上要注意很多地方。

那麼什麼時候該用呢?為什麼有些地方需要用呢?

不使用指針的話,某些情況是沒法賦值給結構體的,接下來看一段程式碼,這段程式碼不使用任何指針,先定義一堆用來測試的物件

type Person struct {  //person结构体,包含年龄,名称,车
    age  int
    name string
    car  Car
}

type Car struct {  //person名下的车
    name string  //车的名字
}

var personMap map[string]Person   //一个存放person的map

func setName(person Person, name string) { //给参数person设置名字
    person.name = name
}

func (person Person) setName(name string) {  //设置名字
    person.name = name
}
func printName(person Person){  //打印person的名字
    fmt.Println(person.name)
}
func (person Person)printName(){  //结构体person自己支持打印名字
    fmt.Println(person.name)
}

然後寫main方法,我會在程式碼裡面註解列印的結果,可以發現很多情況下賦值失敗了。

func main() {
    person := Person{}
    fmt.Println(person)  //{0  {}}
    person.age = 12
    person.name = "小明"
    person.car = Car{"宝马"}
    fmt.Println(person)  //{12 小明 {宝马}},正常赋值给person变量,因为这是在方法里面的变量
    setName(person, "小红")
    fmt.Println(person) //{12 小明 {宝马}},小红赋值失败,传递给setName方法的person没有赋值成功
    person.setName("小红")
    fmt.Println(person) //{12 小明 {宝马}},person自己setName,还是失败
    personMap = make(map[string]Person)
    personMap["test"] = person
    person = personMap["test"]
    person.name = "小红"
    fmt.Println(person) //{12 小红 {宝马}},从map中取出person,给小红赋值成功
    for _, value := range personMap { //遍历map
        fmt.Println(value)//{12 小明 {宝马}},打印的还是小明,而不是小红,说明上面personMap["test"]对象赋值失败
    }
}

接下來改造成使用指標

type Person struct {
    age  int
    name string
    car  Car
}
type Car struct {
    name string
}
var personMap map[string]*Person
func setName(person *Person, name string) {
    person.name = name
}
func (person *Person) setName(name string) {
    person.name = name
}
func printName(person Person){
    fmt.Println(person.name)
}
func (person Person)printName(){
    fmt.Println(person.name)
}

#修改main方法,使用&取址符

func main() {
    person := Person{}
    fmt.Println(person) //{0  {}}
    person.age = 12
    person.name = "小明"
    person.car = Car{"宝马"}
    fmt.Println(person) //打印{12 小明 {宝马}}
    setName(&person, "小红")
    fmt.Println(person) //{12 小红 {宝马}}, 成功赋值!
    person.setName("小黑") 
    fmt.Println(person) //{12 小黑 {宝马}}, 成功赋值!
    personMap = make(map[string]*Person)
    personMap["test"] = &person
    person = *personMap["test"]
    person.name = "小兰"
    fmt.Println(person) //{12 小兰 {宝马}},成功赋值!
    for _, value := range personMap {
        fmt.Println(value) //&{12 小兰 {宝马}},读取的也是正确的小兰
    }
}

所以得出結論,當我們需要修改結構體的變數內容的時候,方法傳入的結構體變數參數需要使用指標,也就是結構體的位址需要修改map中的架構體的變數的時候,也需要使用結構體位址作為map的value

如果只是讀取結構體變量,可以不使用指針,直接傳遞引用即可

##*type這裡的type這個變數存放的東西是地址,這點需要明確,需要使用&type取得到地址。

以上是golang不用指針可以嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn