英文:
Refactor golang function - what type should be used?
问题
可以将以下函数重构为一个函数getResource(name string, resourceType string) []interface{}
:
func getResource(name string, resourceType string) []interface{} {
var resources []interface{}
var err error
switch resourceType {
case "Pod":
pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), getListOption(name))
if err != nil {
panic(err.Error())
}
resources = append(resources, pods.Items...)
case "Service":
services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), getListOption(name))
if err != nil {
panic(err.Error())
}
resources = append(resources, services.Items...)
default:
// handle unsupported resource type
}
return resources
}
这样,你可以通过传入资源类型来获取相应的资源列表。返回类型为[]interface{}
,可以容纳不同类型的资源。
英文:
Could anyone of you tell how to refactor the following functions, please?
I'd like to have one function eg. getResource(name string, resourceType ????) []v1.?????
, but don't know what would be its return type.
func getPods(name string) []v1.Pod {
pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), getListOption(name))
if err != nil {
panic(err.Error())
}
return pods.Items
}
func getServices(name string) []v1.Service {
services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), getListOption(name))
if err != nil {
panic(err.Error())
}
return services.Items
}
答案1
得分: 4
虽然调用方式几乎相同,内容也几乎相同,但它们的类型是不同的。CoreV1().Pods(namespace).List
是:
List(ctx context.Context, opts metav1.ListOptions) (*v1.PodList, error)
但是CoreV1().Services(namespace).List
是:
List(ctx context.Context, opts metav1.ListOptions) (*v1.ServiceList, error)
一个返回 *v1.PodList
,另一个返回 *v1.ServiceList
。这两个不同的对象都有 Items
,但一个是 []*Service
,另一个是 []*Pod
。
我个人认为不要对它们进行封装。我会分别调用底层函数,在两种情况下都使用相同的 CoreV1
客户端。我肯定不会尝试将它们合并为一个函数。
如果有什么可以合并的地方,那就是命名空间和名称:
type ByName struct {
Name string
Namespace string
v1 corev1.CoreV1Interface
}
func (b *ByName) Services(ctx context.Context) ([]v1.Service, error) {
return b.v1.Services(namespace).List(ctx, getListOption(b.Name))
}
func (b *ByName) Pods(ctx context.Context) ([]v1.Pod, error) {
return b.v1.Pods(b.Namespace).List(ctx, getListOption(b.Name))
}
现在你不需要传递名称和命名空间:
b := &ByName{
Name: name,
Namespace: namespace,
v1: clientset.CoreV1(),
}
if svcs, err := b.Services(); err != nil {
return nil, err
} else if pods, err := b.Pods(); err != nil {
return nil, err
} else {
... 继续处理
}
这样你就可以获得简洁性,而无需进行大量的类型检查。
英文:
While the invocation is nearly identical, and the content is nearly identical, they types are different. CoreV1().Pods(namespace).List
is :
List(ctx context.Context, opts metav1.ListOptions) (*v1.PodList, error)
but CoreV1().Services(namespace).List
is
List(ctx context.Context, opts metav1.ListOptions) (*v1.ServiceList, error)
One returns a *v1.PodList
and the other returns a *v1.ServiceList
. Both these distinct objects have Items
, but one is a []*Service
and the other is a []*Pod
.
I personally would think about not wrapping either. I would call the underlying functions instead, using the same CoreV1
client in both cases.
I certainly wouldn't try to combine them into one function.
If there's something to be combined here, it's namespace and name:
type ByName struct {
Name string
Namespace string
v1 corev1.CoreV1Interface
}
func (b *ByName)Services(ctx context.Context) []v1.Service , error {
return b.v1.Services(namespace).List(ctx, getListOption(b.Name))
}
func (b *ByName)Pods(ctx context.Context) []v1.Pod, error {
return b.v1.Pods(b.Namespace).List(ctx, getListOption(b.Name))
}
Now you don't have to pass name and namespace:
b := &ByName{
Name: name,
Namespace: namespace,
v1: clientset.CoreV1(),
}
if svcs, err := b.Services(); err != nil {
return nil, err
} else if pods, err := b.Pods(); err != nil {
return nil, err
} else {
... continue processing
}
And you get the brevity you want without having to do a bunch of type checking.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论