同一个对象接口可以是不同类型的吗?

huangapple go评论142阅读模式
英文:

Can the same Object interface be different type?

问题

我看到这段代码,想知道为什么object可以同时是ServicePod类型?

这段代码在同一个函数体中。

serviceCreateHook := func(_ context.Context, client *MockClient, object ctrlClient.Object) error {
    svc, isSvc := object.(*corev1.Service)
    if !isSvc {
        return nil
    }

    return nil
}

podCreateHook := func(_ context.Context, client *MockClient, object ctrlClient.Object) error {
    pod, isPod := object.(*corev1.Pod)
    if !isPod {
        return nil
    }

    return nil
}

ctrlClient.Object是定义在k8s客户端Object接口中的:

type Object interface {
    metav1.Object
    runtime.Object
}

我认为object.(*corev1.Pod)是使用类型断言来获取接口对象的底层对象。但为什么同一个接口可以是两种类型呢?

**后续问题:**给定一个object,以下两个条件是否都可能为真?即计数器的值是否可能为2?

{
    counter := 0
    pod, isPod := object.(*corev1.Pod)
    if !isPod {
        return nil
    } else {
        counter++
    }
    node, isNode := object.(*corev1.Node)
    if !isNode {
        return nil
    } else {
        counter++
    }
}
英文:

I saw this code and wonder why object can be both Service and Pod type?

The code is in the same function's body.

    serviceCreateHook := func(_ context.Context, client *MockClient, object ctrlClient.Object) error {
		svc, isSvc := object.(*corev1.Service)
		if !isSvc {
			return nil
		}

		return nil
	}

	podCreateHook := func(_ context.Context, client *MockClient, object ctrlClient.Object) error {
		pod, isPod := object.(*corev1.Pod)
		if !isPod {
			return nil
		}

		return nil
	}

ctrlClient.Object is k8s client Object interface defined below:

type Object interface {
	metav1.Object
	runtime.Object
}

I think object.(*corev1.Pod) is using the type assertion to get the underlying object of the interface object. But why the same interface can be both types?

Follow-up question: Given an object, can both of the following be true? i.e., can the counter value ever be 2?

{
    counter := 0
    pod, isPod := object.(*corev1.Pod)
    		if !isPod {
    			return nil
    		} else {
              counter++
            }
    node, isNode := object.(*corev1.Node)
    		if !isNode {
    			return nil
    		} else {
              counter++
            }
}

答案1

得分: 2

TL;DR:

ctrlClient.Object不能同时是两种类型,但是ctrlClient.Object的任何一个实例可以是任意一种类型。

它也可以是任何其他实现了该接口的类型。

Expansion

ctrlClient.Object是一个接口类型。接口只是一个合同,可以由任意数量的不同类型来实现。

你展示的两个“Hook”函数都接受该接口的任何实现,但是在每种情况下,它们显然都有(或将有)依赖于该实现的具体底层类型的行为(根据发布的函数,它们似乎是不完整的,但这似乎是意图)。

因此,每个函数最初对接口进行了类型断言。

如果底层实现不是所需/预期的类型,则该函数与其是相反的。

英文:

TL;DR:

A ctrlClient.Object cannot be both types (at the same time), but any one instance of a ctrlClient.Object could be either type.

It could also be any other type that also implements that interface.

Expansion

ctrlClient.Object is an interface type. An interface is merely a contract that can be implemented by any number of different types.

The two "Hook" funcs that you show both accept any implementation of that interface, but in each case they apparently have (or will have) behaviours that depend on the specific underlying type of that implementation (the funcs appear to be incomplete as posted, but this would seem to be the intent).

Hence, each function initially performs a type assertion on the interface.

If the underlying implementation is not of the required/expected type then the function has some alternate flow compared to when it is.

huangapple
  • 本文由 发表于 2023年3月15日 02:29:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75737066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定