2017-07-14 1 views
0

これは些細な質問であれば私はそれを許して新しくなりました。私はポストのスライスを反復処理し、各ポストのViewsの値をインクリメントしたい:スライスの変更された値を関数から戻す方法は?

func incrementViews(posts []model.Post) []model.Post { 
     for _, v := range posts { 
      v.Views++ 
      fmt.Println(v.Views) //Views incremented by 1 
     } 
     return posts 
    } 

    incrementViews(posts) //Views not changed 

印刷された値が変更されますが、私はincrementViews(posts)を呼び出したときに返される値は変更されませんされています。

私はこれを*&で解決しようとしましたが、おそらく私がPythonの背景から来てポインタや値で変数を移動することを理解していないことが考えられます。

答えて

1

問題のコードは、ローカル変数vを更新しています。スライスを* model.Postに変更するか、またはインデックス演算子を使用してスライスの値を更新します。前者は発信者を変更する必要があります。

func incrementViews(posts []*model.Post) []*model.Post { 
    for _, v := range posts { 
     v.Views++ 
    } 
    return posts 
} 

func incrementViews(posts []model.Post) []model.Post { 
    for i := range posts { 
     posts[i].Views++ 
    } 
    return posts 
} 

EDIT:

どちらの作品に近づき、ここを参照してください:https://play.golang.org/p/90BNOFYaKL

+0

最初の方法でエラーが発生します: '[*] model.Postをタイプ[] * model.Postとして使用することはできません。incrementViewsの引数に投稿します。 – Karlom

+0

@sahaj次に、2つのエラーが発生します。 ] * model.Post)をtype [] model.Post in return argument'として使用し、型[] * model.PostをincrementViewsの引数に入れて使用することはできません。 – Karlom

+0

@Karlom私は信じていますあなたのコメントで礼儀正しくてください。再生例のリンクを追加しました。 – jeevatkm

1

range式は、スライス要素のコピーを返します。したがって、反復処理中にスライス要素を変更する場合は、非常に注意する必要があります。

rangeスライスまたは配列の式は、最初のパラメータをインデックスとして返し、2番目のパラメータをそのインデックスの要素のコピーとして返します。あなたの例では、範囲によって返されたコピーを修正しているため、元のスライス要素に変更が加えられていません。

変更する必要があるのは、[インデックス]でスライス名を参照することです。実際にスライス内の元の要素を参照して元のスライス要素を変更することができます。 jeevatkmの作業例のsecond approachを参照してください。

もう1つの方法は、アドレスのスライスを使用することです。この場合、範囲で返された値を参照することができます。コピーであってもアドレスの場所のコピーであり、元の要素を指しています。 jeevatkmによって与えられた作業例の最初のアプローチを参照してください。

+0

良い講演。しかし、これはどのように作業コードに変換されますか? – Karlom

+0

実例を参照して回答を更新しました。 – sahaj

+0

@shajあなたは私の場合とは無関係の他の回答コメントで遊び場をコピーしました。スライス内の構造体の値を取得するために 'incrementViews'関数を反復しません。 – Karlom

関連する問題