2017-11-11 3 views
4

私はGo新人です。タイプはGoでどのように関数になりますか?

私はsome Kubernetes source codeを見ています。

私はこれを参照してください。私はこれを読むためにhazily方法を知っているが、私は、私は私の専門用語が間違って取得するつもりだと確信している

// GetByKey returns the key if it exists in the list returned by kl. 
func (kl keyLookupFunc) GetByKey(key string) (interface{}, bool, error) { 
    for _, v := range kl() { 
     if v.name == key { 
      return v, true, nil 
     } 
    } 
    return nil, false, nil 
} 

を:どこかkeyLookupFuncと呼ばれるタイプだ、とklが効果的ですそのインスタンスで呼び出され、GetByKeyという名前のこの関数を呼び出すことができます。それは私ので、その型はstringあり、そしてそれは三つの値を返す、などなど

(私はmy best guess as to where it should live in the language specificationで、この特定の建設のためのBNFが表示されていないが、私はこのような構成を見てきました何回か前にkeyを受け入れます信仰の上にそれを取る)ソースコード内の最大高

が、私はこれに気づく:。

// keyLookupFunc adapts a raw function to be a KeyLookup. 
type keyLookupFunc func() []testFifoObject 

OK、そう確かにkeyLookupFuncタイプがあり、そして取る機能があるものを記述するために使用されます0のパラメータを返し、testFifoObjectのスライスを返します。

私はkeyLookupFunc型の変数を手に持っていれば、GetByKeyを "on"に呼び出すことができます。このような状況でどのように関数が型のように振る舞うかは完全にはわかりませんが、私はそれを信じて受け取ります。今

私はこれがすべて使用されているか確認するために見て、私はsee this partial stuff

func TestDeltaFIFO_requeueOnPop(t *testing.T) { 
    f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil) 

    f.Add(mkFifoObj("foo", 10)) 
    _, err := f.Pop(func(obj interface{}) error { 
     if obj.(Deltas)[0].Object.(testFifoObject).name != "foo" { 
      t.Fatalf("unexpected object: %#v", obj) 
     } 
     return ErrRequeue{Err: nil} 
    }) 
    if err != nil { 
     t.Fatalf("unexpected error: %v", err) 
    } 
    if _, ok, err := f.GetByKey("foo"); !ok || err != nil { 
     t.Fatalf("object should have been requeued: %t %v", ok, err) 
    } 

f.GetByKey("foo")呼び出しに注意してください。 fDeltaFIFOへのポインタであり、I just happen to know is returned by NewDeltaFIFOです。

fはどのようにそれはまた、このコードが「上」GetByKeyを呼び出すことができるというkeyLookupFuncようにすることができ、DeltaFIFOへのポインタであることを考えると?これらの点をどのように結びつけるのですか?

注最後f.GetByKeyである:

// GetByKey returns the complete list of deltas for the requested item, 
// setting exists=false if that list is empty. 
// You should treat the items returned inside the deltas as immutable. 
func (f *DeltaFIFO) GetByKey(key string) (item interface{}, exists bool, err error) { 
    f.lock.RLock() 
    defer f.lock.RUnlock() 
    d, exists := f.items[key] 
    if exists { 
     // Copy item's slice so operations on this slice (delta 
     // compression) won't interfere with the object we return. 
     d = copyDeltas(d) 
    } 
    return d, exists, nil 
} 

及びこの二GetByKey方法は、2つの異なるタイプの二つの別個の方法、(同じ名前のメソッドを持つ2つの異なるタイプ)である

+3

'DeltaFIFO' **も**' keyLookupFunc'ではありませんが、**、それはまた、メソッドを持っている**と呼ばれる 'GetByKey' https://github.com/kubernetes/kubernetes/blob/マスター/ステージング/ src/k8s.io/client-go/tools/cache/delta_fifo.go#L392-L402 2つの異なる型は同じ名前のメソッドを持つことができますが、問題はありません。 – mkopriva

+0

ありがとうございます。私はそれを見たに違いありません。どのように恥ずかしい。ただし、この 'GetByKey'関数は[この' .go'ファイル](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io)の残りでは使用されていません/client-go/tools/cache/delta_fifo.go)、そうですか? –

+1

それはそうではないかもしれませんが、多分それは遺産かもしれません、多分それは後の使用を意図したものです、私は知らない。 [この検索](https://github.com/kubernetes/kubernetes/search?utf8=%E2%9C%93&q=keyLookupFunc&type=)を実行すると、その識別子は1年以上の古いドキュメントでのみ使用されていることがわかります。あなたが[この検索](https://github.com/kubernetes/kubernetes/search?utf8=%E2%9C%93&q=testFifoObject&type=)を実行すると、実際の機能がないことがわかります'keyLookupFunc'型...メソッドで関数型に興味があるなら' net/http.HandlerFunc'を見てください。それは有名です。 – mkopriva

答えて

4

// Get returns the complete list of deltas for the requested item, 
// or sets exists=false. 
// You should treat the items returned inside the deltas as immutable. 
func (f *DeltaFIFO) Get(obj interface{}) (item interface{}, exists bool, err error) { 
    key, err := f.KeyOf(obj) 
    if err != nil { 
     return nil, false, KeyError{obj, err} 
    } 
    return f.GetByKey(key) 
} 

とも呼ばれる3:一度ここ(return f.GetByKey(key)delta_fifo.goファイル内)と呼ばれます(f.GetByKey("foo")delta_fifo_test.goファイルで)ここ回:

func TestDeltaFIFO_requeueOnPop(t *testing.T) { 
    f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil) 

    f.Add(mkFifoObj("foo", 10)) 
    _, err := f.Pop(func(obj interface{}) error { 
     if obj.(Deltas)[0].Object.(testFifoObject).name != "foo" { 
      t.Fatalf("unexpected object: %#v", obj) 
     } 
     return ErrRequeue{Err: nil} 
    }) 
    if err != nil { 
     t.Fatalf("unexpected error: %v", err) 
    } 
    if _, ok, err := f.GetByKey("foo"); !ok || err != nil { 
     t.Fatalf("object should have been requeued: %t %v", ok, err) 
    } 

    _, err = f.Pop(func(obj interface{}) error { 
     if obj.(Deltas)[0].Object.(testFifoObject).name != "foo" { 
      t.Fatalf("unexpected object: %#v", obj) 
     } 
     return ErrRequeue{Err: fmt.Errorf("test error")} 
    }) 
    if err == nil || err.Error() != "test error" { 
     t.Fatalf("unexpected error: %v", err) 
    } 
    if _, ok, err := f.GetByKey("foo"); !ok || err != nil { 
     t.Fatalf("object should have been requeued: %t %v", ok, err) 
    } 

    _, err = f.Pop(func(obj interface{}) error { 
     if obj.(Deltas)[0].Object.(testFifoObject).name != "foo" { 
      t.Fatalf("unexpected object: %#v", obj) 
     } 
     return nil 
    }) 
    if err != nil { 
     t.Fatalf("unexpected error: %v", err) 
    } 
    if _, ok, err := f.GetByKey("foo"); ok || err != nil { 
     t.Fatalf("object should have been removed: %t %v", ok, err) 
    } 
} 

そして、他の方法は次のとおりです。

// GetByKey returns the key if it exists in the list returned by kl. 
func (kl keyLookupFunc) GetByKey(key string) (interface{}, bool, error) { 
    for _, v := range kl() { 
     if v.name == key { 
      return v, true, nil 
     } 
    } 
    return nil, false, nil 
} 

、これは使用されません(と呼ばれていません)。

+1

答えの2番目の部分が間違っているようです。[NewDeltaFIFO](https://github.com/kubernetes/kubernetes/blob/2986b37de06fcd1bf94e68b49b6c8d87c389d3c2/staging/src/k8s.io/client-go/tools/cache/delta_fifo。 go#L51)は、 '* DeltaFIFO'のインスタンスを返し、' keyLookupFunc'のインスタンスは返しません。私にとっては、 'keyLookupFunc'とそのメソッド' GetByKey'はどこにも使われていないようです。もちろん、私は何かが欠けています。 – mkopriva

+0

こんにちは。ご回答有難うございます。私は@mkoprivaに同意する傾向があります。あなたが参照する3つの呼び出しは、まさに私が求めているものです。私はここで 'GetByKey'関数呼び出しの"ターゲット "が、おそらく' keyLookupFunc'である可能性があるとは思えません。 –

+1

A.Rの答えは正しいです。あなたが持っている問題は、 'keyLookupFunc'型で' GetByKey'と呼ばれるメソッドが見つかったということですが、 'GetByKey'メソッドがたくさんのレシーバで存在する可能性があります。実際、 'DeltaFIFO'はそれ自身の' GetByKey'(A.Rが最初に参照する)を持っているので、最初にポストされたコードの中に 'keyLookupFunc'レシーバで' GetByKey'を呼び出すものは何もありません。 – sberry

1

機能はGoのファーストクラスの市民であり、メソッドがあり、インターフェイスを実装することさえできます。

https://play.golang.org/p/d-N4OKLirQ

関連する問題