英文:
How can I make a function that works on any type from the k8s package?
问题
抱歉,我是一个语言模型,无法直接运行代码。但是我可以帮你解释一下代码中的问题。
根据你提供的代码和错误信息,问题出在DeleteOldAny
函数中的resource
参数上。错误信息指出interface{}
类型没有实现k8s.io/apimachinery/pkg/runtime.Object
接口的DeepCopyObject
方法。
在Go语言中,接口类型是隐式实现的,而不是显式实现的。这意味着你不能将一个接口类型的指针传递给一个期望接口类型的函数。在你的代码中,resource
参数的类型是interface{}
,而不是一个接口类型。
要解决这个问题,你可以将resource
参数的类型更改为一个接口类型,该接口类型实现了DeepCopyObject
方法。根据你提供的代码,你可以使用batchv1beta1.CronJob
作为接口类型,因为它是一个结构体,并且实现了DeepCopyObject
方法。修改代码如下:
func DeleteOldAny(c client.Client, ctx context.Context, name string, key client.ObjectKey, resource runtime.Object) error {
err := c.Get(ctx, key, resource)
if err == nil {
err := c.Delete(ctx, resource)
if err != nil {
return err
}
} else {
return err
}
return nil
}
然后在调用DeleteOldAny
函数时,将&cronJob
作为resource
参数传递:
return DeleteOldAny(c, ctx, name, key, &cronJob)
这样修改后,你应该能够正确地使用DeleteOldAny
函数,并且可以在不同类型上重用它。
希望这可以帮助到你!如果你还有其他问题,请随时提问。
英文:
Sorry I'm quite a noob at Go so hope this isn't a stupid question. I know pointers in a general sense but struggling with Go semantics.
I can't get this to work:
func DeleteOldCronJob(c client.Client, ctx context.Context, namespace string, name string) error {
cronJob := batchv1beta1.CronJob{}
key := client.ObjectKey{
Namespace: namespace,
Name: name,
}
return DeleteOldAny(c, ctx, name, key, &cronJob)
}
func DeleteOldAny(c client.Client, ctx context.Context, name string, key client.ObjectKey, resource interface{}) error {
err := c.Get(ctx, key, resource)
if err == nil {
err := c.Delete(ctx, resource)
if err != nil {
return err
}
} else {
return err
}
return nil
}
I get an error:
interface {} does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing DeepCopyObject method)
The point is so that I can reuse DeleteOldAny on multiple different types, to make my codebase more compact (I could just copy+paste DeleteOldCronjob and change the type).
As far as I read, pointers to interfaces in Go are usually wrong. Also, the k8s type I'm importing is just a struct. So, I thought since it's a struct not an interface I should pass resource a a pointer like:
err := c.Get(ctx, key, &resource)
But that gives me another error:
*interface {} is pointer to interface, not interface
So I'm a bit stuck. Am I doomed to copy+paste the same function for each type or is it a simple syntax mistake I'm making?
答案1
得分: 1
func (client.Reader).Get(ctx context.Context, key types.NamespacedName, obj client.Object) error
Get从Kubernetes集群中检索给定对象键的obj。obj必须是一个结构体指针,以便可以使用服务器返回的响应更新obj。
所以这个想法是正确的,采用模块化的方法并停止重用代码。
但是实现是错误的,obj应该是您尝试从集群中获取的资源,应该将其作为结构体指针传递给函数。
err := c.Get(ctx, key, &resource)
这里的resource应该是一个结构体,就像Get,delete等函数期望传递指向相应对象的指针一样。
英文:
func (client.Reader).Get(ctx context.Context, key types.NamespacedName, obj client.Object) error
Get retrieves an obj for the given object key from the Kubernetes Cluster. obj must be a struct pointer so that obj can be updated with the response returned by the Server.
so the idea is right to have modular approach and stop reusing the code .
But implementation is wrong , the obj would be the resource you are trying to fetch from cluster which should be passed in the function as a struct pointer.
err := c.Get(ctx, key, &resource)
here resource should be a struct as Get , delete etc. expects as pointer to the respective object to be passed .
答案2
得分: 0
基本上答案是使用unstructured包。
我认为你不能在没有具体类型的情况下使用client.Get()
,这太荒谬了。Go确实是一种僵硬而冗长的语言,不是吗?
英文:
Pretty much the answer is to use the unstructured package.
I don't think you can do client.Get()
without a concrete type, which is ridiculous. Go really is a stiff and verbose language, isn't it?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论