2017-01-20 21 views
1

私は学びつつ、ドキュメントのいくつかのサンプルコードについて質問しました。golangポインタ受信者と値受信者

私はポインタレシーバとバリューレシーバについて学びました。オブジェクト自体を変更したい場合は、ポインタレシーバを使用する必要があります。 Iはgo documentationのインターフェイスの詳細を読み、このコードのチャンクを発見した。

type Sequence []int 

// Methods required by sort.Interface. 
func (s Sequence) Len() int { 
    return len(s) 
} 
func (s Sequence) Less(i, j int) bool { 
    return s[i] < s[j] 
} 
func (s Sequence) Swap(i, j int) { 
    s[i], s[j] = s[j], s[i] 
} 

値レシーバを使用LessLen方法は理にかなって、彼らはデータを返すとSequence状態を変更されていないため。しかし、Swapの例では、状態を変更しようとしているときに値受信機を使用している理由が不思議です。これは間違いですか、あるいは値/ポインタ受信者に何らかの欠陥があるという私の理解ですか?

ありがとうございます!

+1

'Sequence'は参照型であるため、' Swap'関数はスライスの基礎となる値を入れ替えます。スライスの良い記事がここにあります:https://blog.golang.org/go-slices-usage-and-internals – squiguy

+1

あなたは 's'を修正していません。あなたは 's [i]'と 's [j]'を変更しています。 –

答えて

3

@ squiguyのコメントを少し拡張するために、スライスオブジェクトの値は、基本的な配列への参照そのものです。スライスが始まる配列内の要素へのポインタ、スラ​​イスの長さ、スライスの容量(スライスの先頭から配列の終わりまでの配列内の要素の数)。関数にスライスを渡すと、それは値によって渡される上記の情報なので、関数内のスライスは引き続き同じ基本配列を参照します。これは、スライス自体が値渡しであっても、Swapがスライス内の要素を入れ替えることができる方法です。

+0

これは非常に意味がある、私はスライスが常に配列を参照していたことを理解していない。これが特殊なケースであれば、類似しているGoには他のタイプがありますか? – phouse512

+2

マップは同様の方法で動作します。関数にマップを渡して関数がマップを変更すると、呼び出し元にその変更が表示されます。チャネルはこのグループ(参照型)にもありますが、チャネルを関数に渡すと、関数と呼び出し元の両方が同じチャネルへの参照を持つことがもう少し明らかです。 –

関連する問題