12

このような構造体がある場合

type myStruct struct {
    mystring string
    myint int
}

そして、このような新しいmyStructを返す関数がある場合

func New() myStruct {
    s := myStruct{}

    s.mystring = "string"
    s.myint = 1

    return s
}

最初に「s」変数に格納してから返すので、私の関数は実際には1つではなく2つのmyStruct値を作成していますか?

もしそうなら、私が最初にそれを変数に保存しないことを確認することはより良い習慣ですか?

4

3 に答える 3

11

returnステートメントは、myStructオブジェクト値のコピーを返します。それが小さなオブジェクトである場合、これは問題ありません。

呼び出し元がこのオブジェクトを変更できるようにし、構造体にレシーバーとしてポインターを使用するメソッドがある場合は、代わりに構造体へのポインターを返す方が理にかなっています。

func New() *myStruct {
    s := myStruct{}

    s.mystring = "string"
    s.myint = 1

    return &s
}

値のメモリアドレスとポインタの戻りタイプを比較すると、コピーが発生していることがわかります。http: //play.golang.org/p/sj6mivYSHg

package main

import (
    "fmt"
)

type myStruct struct {
    mystring string
    myint    int
}

func NewObj() myStruct {
    s := myStruct{}
    fmt.Printf("%p\n", &s)

    return s
}

func NewPtr() *myStruct {
    s := &myStruct{}
    fmt.Printf("%p\n",s)
    return s
}

func main() {

    o := NewObj()
    fmt.Printf("%p\n",&o)

    p := NewPtr()
    fmt.Printf("%p\n",p)
}


0xf8400235a0 // obj inside NewObj()
0xf840023580 // obj returned to caller
0xf840023640 // ptr inside of NewPtr()
0xf840023640 // ptr returned to caller
于 2012-12-20T02:02:06.833 に答える
3

私は間違いなくGoの専門家ではありませんが(または初心者でも:))、@ max.haredoomで述べたように、関数のシグネチャ自体に変数を割り当てることができます。sこのようにして、return:のを省略することもできます。

package main

import "fmt"

type myStruct struct {
    mystring string
    myint    int
}

func New() (s myStruct) {
    s.mystring = "string"
    s.myint = 1

    return
}

func main() {
    r := New()
    fmt.Println(r)
}

// Outputs {string 1}

私がEffectiveGoで出会った例では、これがこの種のことを行う最も一般的な方法のようですが、繰り返しになりますが、私はこの主題に関する権威ではありません(実際のパフォーマンス)。

于 2012-12-20T01:51:54.320 に答える
0

deferを使って答えを見つけたと思います。

myStruct値に延期された変更があるように、関数を更新しました。これは、返品後、相手側で受信される前に発生することを意味します。

これを行うと、呼び出し元が受け取った構造体に更新された値が表示されないため、実際にコピーを返しているように見えます。

func New() myStruct {
    s := myStruct{}

    defer func() {
        s.mystring = "new value" // defer an update to the value
    }()

    s.mystring = "string"
    s.myint = 1

    return s
}

func main() {

    b := New()

    fmt.Println(b) // still shows the original value
}

http://play.golang.org/p/WWQi8HpDny

于 2012-12-20T02:00:07.197 に答える