Ich bin ein Go-Rookie.Wie wird ein Typ in Go zu einer Funktion?
Ich sehe some Kubernetes source code.
Ich sehe dies:
// 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
}
Ich weiß, dunstig, wie dies zu lesen, aber ich bin sicher, ich werde meine Terminologie falsch machen: Es gibt eine Art irgendwo keyLookupFunc
genannt, und kl
ist effektiv ein Instanz davon, und diese Funktion mit dem Namen GetByKey
kann darauf aufgerufen werden. Er akzeptiert ein key
, dessen Typ string
ist, und es gibt drei Werte, etc. etc.
(I für diese spezielle Konstruktion finden Sie in die BNF nicht zu my best guess as to where it should live in the language specification, aber ich habe diese Konstruktion mehrmals vor, so gesehen, die ich nehmen sie es auf den Glauben)
Higher im Quellcode, ich dies bemerken.
// keyLookupFunc adapts a raw function to be a KeyLookup.
type keyLookupFunc func() []testFifoObject
OK, also in der Tat keyLookupFunc
ist eine Art, und es wird verwendet, um etwas zu beschreiben, die eine Funktion ist, die nimmt Zero-Parameter und gibt ein Stück testFifoObject
s zurück.
So naiv, wenn ich eine keyLookupFunc
-type Variable in meiner Hand habe, sollte ich in der Lage sein, GetByKey
"on" it anzurufen. Ich bin mir nicht ganz sicher, wie sich eine Funktion in dieser Situation wie ein Typ verhalten kann, aber ich nehme es im Glauben.
Wenn ich jetzt schauen, um zu sehen, wie das alles verwendet wird, ich 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)
}
Notiere die f.GetByKey("foo")
Aufruf. f
ist ein Zeiger auf eine , die I just happen to know is returned by NewDeltaFIFO
.
Da f
ein Zeiger auf eine DeltaFIFO
ist, wie kann es auch ein keyLookupFunc
so beschaffen sein, dass dieser Code GetByKey
„auf“ es nennen kann? Wie verbinde ich diese Punkte?
'DeltaFIFO' ** ist auch nicht **' keyLookupFunc', aber ** es hat auch eine Methode ** genannt 'GetByKey' https://github.com/kubernetes/kubernetes/blob/ master/staging/src/k8s.io/client-gehen/tools/cache/delta_fifo.go # L392-L402. Zwei verschiedene Typen können eine Methode mit dem gleichen Namen haben, kein Problem. – mkopriva
Vielen Dank; Ich hätte das sehen sollen; wie peinlich. Das heißt aber, dass diese 'GetByKey'-Funktion im Rest dieser [.go'-Datei] nicht verwendet wird (https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io /client-go/tools/cache/delta_fifo.go), oder? –
Es scheint nicht, vielleicht ist es Erbe, vielleicht ist es etwas für den späteren Gebrauch bestimmt, ich weiß es nicht. Wenn Sie [diese Suche] (https://github.com/kubernetes/kubernetes/search?utf8=%E2%9C%93&q=keyLookupFunc&type=) ausführen, können Sie sehen, dass diese Kennung nur in einer einjährigen Dokumentation verwendet wird. .. Und wenn du [diese Suche] (https://github.com/kubernetes/kubernetes/search?utf8=%E2%9C%93&q=testFifoObject&type=) machst, wirst du sehen, dass es keine tatsächliche Funktion gibt, die mit der übereinstimmt 'keyLookupFunc' Typ ... Übrigens, wenn Sie an Funktionstypen mit Methoden interessiert sind, schauen Sie in' net/http.HandlerFunc', es ist berühmt. – mkopriva