在函数中编写结构字段

huangapple go评论85阅读模式
英文:

Go, write struct fields in function

问题

我是你的中文翻译助手,以下是翻译好的内容:

我是Go语言的新手,我不明白为什么在结构体函数中不使用指针时,结构体字段的值不会被写入。这里有一个例子,当调用setValue()函数时,它会执行,但值不会被设置:

type myStruct struct {
    value string
}

func (m myStruct) getValue() string            { return m.value }
func (m myStruct) setValue(val string)         { m.value = val }
func (m *myStruct) getValuePointer() string    { return m.value }
func (m *myStruct) setValuePointer(val string) { m.value = val }

func TestStruct(t *testing.T) {
    obj := myStruct{value: "initValue"}

    fmt.Printf("Use setValue function\n")
    obj.setValue("setValue_Called")
    fmt.Printf("obj.getValue()        = [%v]\n", obj.getValue())
    fmt.Printf("obj.getValuePointer() = [%v]\n", obj.getValuePointer())

    fmt.Printf("Use setValuePointer function\n")
    obj.setValuePointer("setValuePointer_Called")
    fmt.Printf("obj.getValue()        = [%v]\n", obj.getValue())
    fmt.Printf("obj.getValuePointer() = [%v]\n", obj.getValuePointer())
}

这段代码输出的结果是:

Use setValue function
obj.getValue()        = [initValue]
obj.getValuePointer() = [initValue]
Use setValuePointer function
obj.getValue()        = [setValuePointer_Called]
obj.getValuePointer() = [setValuePointer_Called]

有人可以帮助我理解在创建结构体函数时使用或不使用指针时发生了什么吗?
此外,setValue函数在没有错误或警告的情况下执行,这让我感到非常害怕 在函数中编写结构字段

英文:

I am new in Go and I don't understand why the struct field values are not written if I don't use a pointer in the struct functions. Here an example, when setValue() is called, it executes but the value is not set:

type myStruct struct {
    value string
}

func (m myStruct) getValue() string            { return m.value }
func (m myStruct) setValue(val string)         { m.value = val }
func (m *myStruct) getValuePointer() string    { return m.value }
func (m *myStruct) setValuePointer(val string) { m.value = val }

func TestStruct(t *testing.T) {
    obj := myStruct{value: "initValue"}

    fmt.Printf("Use setValue function\n")
    obj.setValue("setValue_Called")
    fmt.Printf("obj.getValue()        = [%v]\n", obj.getValue())
    fmt.Printf("obj.getValuePointer() = [%v]\n", obj.getValuePointer())

    fmt.Printf("Use setValuePointer function\n")
    obj.setValuePointer("setValuePointer_Called")
    fmt.Printf("obj.getValue()        = [%v]\n", obj.getValue())
    fmt.Printf("obj.getValuePointer() = [%v]\n", obj.getValuePointer())
}

this code prints:

Use setValue function
obj.getValue()        = [initValue]
obj.getValuePointer() = [initValue]
Use setValuePointer function
obj.getValue()        = [setValuePointer_Called]
obj.getValuePointer() = [setValuePointer_Called]

Could someone help me understanding what happens under the hood when a struct function is created using or not using a pointer?
In addition, the fact that setValue executes with no errors or warnings is quite scaring to me 在函数中编写结构字段

答案1

得分: 1

定义方法时需要记住一件事:

方法就像普通函数一样,当你调用setValue()函数时,发生的情况如下所示。

package main

import "fmt"

type vertex struct {
	x int
	y int
}

func main() {
	var v vertex
	fmt.Println(v.setVertex(1, 2))
	fmt.Println(v)
}

func (v vertex) setVertex(x, y int) vertex {
	v.x = x
	v.y = y
	return v
}

使用值接收器时,setVertex方法在原始顶点值的副本上操作。(这与任何其他函数参数的行为相同。)该方法具有值作为接收器,因此它获取副本而不是原始顶点。

如果你想要改变任何变量或结构体,我们需要传递它的地址,否则被调用的函数只会接收到该变量的副本。

这在Go之旅中有明确的解释。

英文:

One thing to remember while you were defining methods is:

Methods are like normal functions, and when you were calling setValue() function, what's happening is this.

package main

import "fmt"

type vertex struct {
	x int
	y int
}

func main() {
	var v vertex
	fmt.Println(v.setVertex(1, 2))
	fmt.Println(v)
/*  v = v.setVertex(1,2)
    // we are assigning the returned variable address to v.
    fmt.Println(v)
*/
    
}


// With a value receiver, the setVertex method operates on a copy of the 
// original vertex value. (This is the same behavior as for any other
// function argument.) 
// This methods has a value as a reciver, so it gets the copy not the 
// original vertex.

func (v vertex) setVertex(x, y int) vertex {
// Here it is similar to creating a new variable with name 'v',
// Go is lexically scoped using blocks, so this variable exists only 
// in this block, while it is returned we are printing it but we didn't
// store it in another variable.
	v.x = x
	v.y = y
	return v
}

// If you want to change any variable or struct, we need to pass its 
// address, else only copy of that variable is received by the called
// function.

This is clearly explained in gotour

huangapple
  • 本文由 发表于 2017年6月24日 18:11:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/44735281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定