I am trying to write a function which takes anything that implements a certain interface as an argument.
I have defined an interface KeyProvider
which specifies a GetKey()
method. I have defined a function that uses this interface ToKeys()
.
type KeyProvider interface {
GetKey() *datastore.Key
}
func ToKeys(l []*KeyProvider) []*datastore.Key {
keys := make([]*datastore.Key, len(l))
for i, vp := range l {
v := *vp
keys[i] = v.GetKey()
}
return keys
}
I have implemented this interface on a struct User
.
type User struct {
Key *datastore.Key
}
func (u *User) GetKey() *datastore.Key {
return u.Key
}
I try to use the ToKeys()
method.
func foo(users []*User) {
keys := ToKeys(users)
}
But I get this error:
cannot use users (type []*User) as type []*KeyProvider in argument to ToKeys
Why? And how can I get something like this working?
always keep in mind, Go requires explicit type conversions.
1.func ToKeys(l []*KeyProvider) []*datastore.Key
should be func ToKeys(l []KeyProvider) []*datastore.Key
.
should almost never use pointer to an interface, use interface.
2.not allow to convert []*User
to []KeyProvider
directly, because of different representation in memory (if you are interesting about slice's internal).
you need to convert the slice manually, for example:
func foo(t []*User) {
s := make([]KeyProvider, len(t))
for i, v := range t {
s[i] = v
}
keys := ToKeys(s)
}
check this two urls:
https://golang.org/doc/faq#convert_slice_of_interface https://golang.org/doc/faq#convert_slice_with_same_underlying_type