I am a Go rookie.
I am looking at some Kubernetes source code.
I see this:
// 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
}
I know hazily how to read this, but I'm sure I'm going to get my terminology wrong: There's a type somewhere called keyLookupFunc
, and kl
is effectively an instance of it, and this function, named GetByKey
can be called on it. It accepts a key
whose type is string
, and it returns three values, etc. etc.
(I don't see the BNF for this particular construction at my best guess as to where it should live in the language specification, but I've seen this construction several times before so I take it on faith.)
Higher up in the source code, I notice this:
// keyLookupFunc adapts a raw function to be a KeyLookup.
type keyLookupFunc func() []testFifoObject
OK, so indeed keyLookupFunc
is a type, and it is used to describe something that is a function that takes zero parameters and returns a slice of testFifoObject
s.
So naïvely, if I have a keyLookupFunc
-typed variable in my hand, I should be able to call GetByKey
"on" it. I am not entirely sure how a function can behave like a type in this situation, but I'll take it on faith.
Now when I look to see how this is all used, I 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)
}
Note the f.GetByKey("foo")
invocation. f
is a pointer to a DeltaFIFO
, which I just happen to know is returned by NewDeltaFIFO
.
Given that f
is a pointer to a DeltaFIFO
, how can it also be a keyLookupFunc
such that this code can call GetByKey
"on" it? How do I connect these dots?