教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang系列(四)之面向接口编程

Golang系列(四)之面向接口编程

发布时间:2021-12-25   编辑:jiaochengji.com
教程集为您提供Golang系列(四)之面向接口编程等资源,欢迎您收藏本站,我们将为您提供最新的Golang系列(四)之面向接口编程资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h2 id="1-接口多态">1. 接口[多态]</h2>

​多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

简而言之,就是允许将子类类型的指针赋值给父类类型的指针。

即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态分为编译时多态(静态多态)和运行时多态(动态多态),编译时多态一般通过方法重载实现,运行时多态一般通过方法重写实现。

<h3 id="11-接口概念">1.1 接口概念</h3> <blockquote>

接口类型可以看作是类型系统中一种特殊的类型,而实例就是实现了该接口的具体结构体类型。

接口类型与实现了该接口的结构体对象之间的关系好比变量类型与变量之间的关系。

</blockquote>

接口即一组方法定义的集合,定义了对象的一组行为,由具体的类型实例实现具体的方法。换句话说,一个接口就是定义(规范或约束),而方法就是实现,接口的作用应该是将定义与实现分离,降低耦合度。习惯用“er”结尾来命名,例如“Reader”。接口与对象的关系是多对多,即一个对象可以实现多个接口,一个接口也可以被多个对象实现。

​ 接口是Go语言整个类型系统的基石,其他语言的接口是不同组件之间的契约的存在,对契约的实现是强制性的,必须显式声明实现了该接口,这类接口称之为“侵入式接口”。而Go语言的接口是隐式存在,只要实现了该接口的所有函数则代表已经实现了该接口,并不需要显式的接口声明

<ul><li>接口的比喻</li></ul>

​ 你的电脑上只有一个USB接口。这个USB接口可以接MP3,数码相机,摄像头,鼠标,键盘等。。。所有的上述硬件都可以公用这个接口,有很好的扩展性,该USB接口定义了一种规范,只要实现了该规范,就可以将不同的设备接入电脑,而设备的改变并不会对电脑本身有什么影响(低耦合)

<ul><li>面向接口编程</li></ul>

接口表示调用者和设计者的一种约定,在多人合作开发同一个项目时,事先定义好相互调用的接口可以大大提高开发的效率。接口是用类来实现的,实现接口的类必须严格按照接口的声明来实现接口提供的所有功能。有了接口,就可以在不影响现有接口声明的情况下,修改接口的内部实现,从而使兼容性问题最小化。

面向接口编程可以分为三方面:制定者(或者叫协调者),实现者(或者叫生产者),调用者(或者叫消费者)

​ 当其他设计者调用了接口后,就不能再随意更改接口的定义,否则项目开发者事先的约定就失去了意义。但是可以在类中修改相应的代码,完成需要改动的内容。

<h3 id="12-非侵入式接口">1.2 非侵入式接口</h3>

非侵入式接口:一个类只需要实现了接口要求的所有函数就表示实现了该接口,并不需要显式声明

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> File <span class="hljs-keyword">struct</span>{ <span class="hljs-comment">//类的属性</span> } <span class="hljs-comment">//File类的方法</span> <span class="hljs-keyword">func</span> (f *File) Read(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) <span class="hljs-keyword">func</span> (f *File) Write(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) <span class="hljs-keyword">func</span> (f *File) Seek(off <span class="hljs-typename">int64</span>,whence <span class="hljs-typename">int</span>) (pos <span class="hljs-typename">int64</span>,err error) <span class="hljs-keyword">func</span> (f *File) Close() error <span class="hljs-comment">//接口1:IFile</span> <span class="hljs-keyword">type</span> IFile <span class="hljs-keyword">interface</span>{ Read(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) Write(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) Seek(off <span class="hljs-typename">int64</span>,whence <span class="hljs-typename">int</span>) (pos <span class="hljs-typename">int64</span>,err error) Close() error } <span class="hljs-comment">//接口2:IReader</span> <span class="hljs-keyword">type</span> IReader <span class="hljs-keyword">interface</span>{ Read(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) } <span class="hljs-comment">//接口赋值,File类实现了IFile和IReader接口,即接口所包含的所有方法</span> <span class="hljs-keyword">var</span> file1 IFile = <span class="hljs-built_in">new</span>(File) <span class="hljs-keyword">var</span> file2 IReader = <span class="hljs-built_in">new</span>(File)</code></pre> <h3 id="13-接口赋值">1.3 接口赋值</h3>

只要类实现了该接口的所有方法,即可将该类赋值给这个接口,接口主要用于多态化方法。即对接口定义的方法,不同的实现方式。

接口赋值:
1)将对象实例赋值给接口

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> IUSB <span class="hljs-keyword">interface</span>{ <span class="hljs-comment">//定义IUSB的接口方法</span> } <span class="hljs-comment">//方法定义在类外,绑定该类,以下为方便,备注写在类中</span> <span class="hljs-keyword">type</span> MP3 <span class="hljs-keyword">struct</span>{ <span class="hljs-comment">//实现IUSB的接口,具体实现方式是MP3的方法</span> } <span class="hljs-keyword">type</span> Mouse <span class="hljs-keyword">struct</span>{ <span class="hljs-comment">//实现IUSB的接口,具体实现方式是Mouse的方法</span> } <span class="hljs-comment">//接口赋值给具体的对象实例MP3</span> <span class="hljs-keyword">var</span> usb IUSB =<span class="hljs-built_in">new</span>(MP3) usb.Connect() usb.Close() <span class="hljs-comment">//接口赋值给具体的对象实例Mouse</span> <span class="hljs-keyword">var</span> usb IUSB =<span class="hljs-built_in">new</span>(Mouse) usb.Connect() usb.Close()</code></pre>

2)将接口赋值给另一个接口

<ol><li>只要两个接口拥有相同的方法列表(与次序无关),即是两个相同的接口,可以相互赋值</li><li>接口赋值只需要接口A的方法列表是接口B的子集(即假设接口A中定义的所有方法,都在接口B中有定义),那么B接口的实例可以赋值给A的对象。反之不成立,即子接口B包含了父接口A,因此可以将子接口的实例赋值给父接口。</li><li>即子接口实例实现了子接口的所有方法,而父接口的方法列表是子接口的子集,则子接口实例自然实现了父接口的所有方法,因此可以将子接口实例赋值给父接口。</li></ol><pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> Writer <span class="hljs-keyword">interface</span>{ <span class="hljs-comment">//父接口</span> Write(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) } <span class="hljs-keyword">type</span> ReadWriter <span class="hljs-keyword">interface</span>{ <span class="hljs-comment">//子接口</span> Read(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) Write(buf []<span class="hljs-typename">byte</span>) (n <span class="hljs-typename">int</span>,err error) } <span class="hljs-keyword">var</span> file1 ReadWriter=<span class="hljs-built_in">new</span>(File) <span class="hljs-comment">//子接口实例</span> <span class="hljs-keyword">var</span> file2 Writer=file1 <span class="hljs-comment">//子接口实例赋值给父接口</span></code></pre> <h3 id="14-接口查询">1.4 接口查询</h3>

若要在 switch 外判断一个接口类型是否实现了某个接口,可以使用“逗号 ok ”。

value, ok := Interfacevariable.(implementType)

其中 Interfacevariable 是接口变量(接口值),implementType 为实现此接口的类型,value 返回接口变量实际类型变量的值,如果该类型实现了此接口返回 true。

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//判断file1接口指向的对象实例是否是File类型</span> <span class="hljs-keyword">var</span> file1 Writer=... <span class="hljs-keyword">if</span> file5,ok:=file1.(File);ok{ ... }</code></pre> <h3 id="15-接口类型查询">1.5 接口类型查询</h3>

在 Go 中,要判断传递给接口值的变量类型,可以在使用 type switch 得到。(type)只能在 switch 中使用。

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// 另一个实现了 I 接口的 R 类型</span> <span class="hljs-keyword">type</span> R <span class="hljs-keyword">struct</span> { i <span class="hljs-typename">int</span> } <span class="hljs-keyword">func</span> (p *R) Get() <span class="hljs-typename">int</span> { <span class="hljs-keyword">return</span> p.i } <span class="hljs-keyword">func</span> (p *R) Put(v <span class="hljs-typename">int</span>) { p.i = v } <span class="hljs-keyword">func</span> f(p I) { <span class="hljs-keyword">switch</span> t := p.(<span class="hljs-keyword">type</span>) { <span class="hljs-comment">// 判断传递给 p 的实际类型</span> <span class="hljs-keyword">case</span> *S: <span class="hljs-comment">// 指向 S 的指针类型</span> <span class="hljs-keyword">case</span> *R: <span class="hljs-comment">// 指向 R 的指针类型</span> <span class="hljs-keyword">case</span> S: <span class="hljs-comment">// S 类型</span> <span class="hljs-keyword">case</span> R: <span class="hljs-comment">// R 类型</span> <span class="hljs-keyword">default</span>: <span class="hljs-comment">//实现了 I 接口的其他类型</span> } }</code></pre> <h3 id="16-接口组合">1.6 接口组合</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//接口组合类似类型组合,只不过只包含方法,不包含成员变量</span> <span class="hljs-keyword">type</span> ReadWriter <span class="hljs-keyword">interface</span>{ <span class="hljs-comment">//接口组合,避免代码重复</span> Reader <span class="hljs-comment">//接口Reader</span> Writer <span class="hljs-comment">//接口Writer</span> }</code></pre> <h3 id="17-any类型空接口">1.7 Any类型[空接口]</h3>

每种类型都能匹配到空接口:interface{}。空接口类型对方法没有任何约束(因为没有方法),它能包含任意类型,也可以实现到其他接口类型的转换。如果传递给该接口的类型变量实现了转换后的接口则可以正常运行,否则出现运行时错误。

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//interface{}即为可以指向任何对象的Any类型,类似Java中的Object类</span> <span class="hljs-keyword">var</span> v1 <span class="hljs-keyword">interface</span>{}=<span class="hljs-keyword">struct</span>{X <span class="hljs-typename">int</span>}<span class="hljs-number">{1</span>} <span class="hljs-keyword">var</span> v2 <span class="hljs-keyword">interface</span>{}=<span class="hljs-string">"abc"</span> <span class="hljs-keyword">func</span> DoSomething(v <span class="hljs-keyword">interface</span>{}) { <span class="hljs-comment">//该函数可以接收任何类型的参数,因为任何类型都实现了空接口</span> <span class="hljs-comment">// ...</span> }</code></pre> <h3 id="18-接口的代码示例">1.8 接口的代码示例</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//接口animal</span> <span class="hljs-keyword">type</span> Animal <span class="hljs-keyword">interface</span> { Speak() <span class="hljs-typename">string</span> } <span class="hljs-comment">//Dog类实现animal接口</span> <span class="hljs-keyword">type</span> Dog <span class="hljs-keyword">struct</span> { } <span class="hljs-keyword">func</span> (d Dog) Speak() <span class="hljs-typename">string</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">"Woof!"</span> } <span class="hljs-comment">//Cat类实现animal接口</span> <span class="hljs-keyword">type</span> Cat <span class="hljs-keyword">struct</span> { } <span class="hljs-keyword">func</span> (c Cat) Speak() <span class="hljs-typename">string</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">"Meow!"</span> } <span class="hljs-comment">//Llama实现animal接口</span> <span class="hljs-keyword">type</span> Llama <span class="hljs-keyword">struct</span> { } <span class="hljs-keyword">func</span> (l Llama) Speak() <span class="hljs-typename">string</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">"?????"</span> } <span class="hljs-comment">//JavaProgrammer实现animal接口</span> <span class="hljs-keyword">type</span> JavaProgrammer <span class="hljs-keyword">struct</span> { } <span class="hljs-keyword">func</span> (j JavaProgrammer) Speak() <span class="hljs-typename">string</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">"Design patterns!"</span> } <span class="hljs-comment">//主函数</span> <span class="hljs-keyword">func</span> main() { animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}} <span class="hljs-comment">//利用接口实现多态</span> <span class="hljs-keyword">for</span> _, animal := <span class="hljs-keyword">range</span> animals { fmt.Println(animal.Speak()) <span class="hljs-comment">//打印不同实现该接口的类的方法返回值</span> } }</code></pre> <h2 id="2-client-go中接口的使用分析">2. client-go中接口的使用分析</h2>

以下以<code>k8s.io/client-go/kubernetes/typed/core/v1/pod.go</code>的pod对象做分析。

<h3 id="21-接口设计与定义">2.1 接口设计与定义</h3> <h4 id="211-接口组合">2.1.1 接口组合</h4> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// PodsGetter has a method to return a PodInterface.</span> <span class="hljs-comment">// A group's client should implement this interface.</span> <span class="hljs-keyword">type</span> PodsGetter <span class="hljs-keyword">interface</span> { Pods(namespace <span class="hljs-typename">string</span>) PodInterface }</code></pre> <h4 id="index1">2.1.2 接口定义</h4> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// PodInterface has methods to work with Pod resources.</span> <span class="hljs-keyword">type</span> PodInterface <span class="hljs-keyword">interface</span> { Create(*v1.Pod) (*v1.Pod, error) Update(*v1.Pod) (*v1.Pod, error) UpdateStatus(*v1.Pod) (*v1.Pod, error) Delete(name <span class="hljs-typename">string</span>, options *meta_v1.DeleteOptions) error DeleteCollection(options *meta_v1.DeleteOptions, listOptions meta_v1.ListOptions) error Get(name <span class="hljs-typename">string</span>, options meta_v1.GetOptions) (*v1.Pod, error) List(opts meta_v1.ListOptions) (*v1.PodList, error) Watch(opts meta_v1.ListOptions) (watch.Interface, error) Patch(name <span class="hljs-typename">string</span>, pt types.PatchType, data []<span class="hljs-typename">byte</span>, subresources ...<span class="hljs-typename">string</span>) (result *v1.Pod, err error) PodExpansion }</code></pre>

<code>PodInterface</code>接口定义了pod对象所使用的方法,一般为增删改查等。其他kubernetes资源对象的接口定义类似,区别在于入参和出参与对象相关。例如<code>Create(*v1.Pod) (*v1.Pod, error)</code>方法定义的入参出参为<code>*v1.Pod</code>。如果要实现该接口,即实现该接口的所有方法。

<h3 id="index2">2.2 接口的实现</h3> <h4 id="221-结构体的定义">2.2.1 结构体的定义</h4> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// pods implements PodInterface</span> <span class="hljs-keyword">type</span> pods <span class="hljs-keyword">struct</span> { client rest.Interface ns <span class="hljs-typename">string</span> }</code></pre> <h4 id="222-new函数构造函数">2.2.2 new函数[构造函数]</h4> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// newPods returns a Pods</span> <span class="hljs-keyword">func</span> newPods(c *CoreV1Client, namespace <span class="hljs-typename">string</span>) *pods { <span class="hljs-keyword">return</span> &pods{ client: c.RESTClient(), ns: namespace, } }</code></pre> <h4 id="223-方法的实现">2.2.3 方法的实现</h4>

Get

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// Get takes name of the pod, and returns the corresponding pod object, and an error if there is any.</span> <span class="hljs-keyword">func</span> (c *pods) Get(name <span class="hljs-typename">string</span>, options meta_v1.GetOptions) (result *v1.Pod, err error) { result = &v1.Pod{} err = c.client.Get(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). Name(name). VersionedParams(&options, scheme.ParameterCodec). Do(). Into(result) <span class="hljs-keyword">return</span> }</code></pre>

List

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// List takes label and field selectors, and returns the list of Pods that match those selectors.</span> <span class="hljs-keyword">func</span> (c *pods) List(opts meta_v1.ListOptions) (result *v1.PodList, err error) { result = &v1.PodList{} err = c.client.Get(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). VersionedParams(&opts, scheme.ParameterCodec). Do(). Into(result) <span class="hljs-keyword">return</span> }</code></pre>

Create

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// Create takes the representation of a pod and creates it. Returns the server's representation of the pod, and an error, if there is any.</span> <span class="hljs-keyword">func</span> (c *pods) Create(pod *v1.Pod) (result *v1.Pod, err error) { result = &v1.Pod{} err = c.client.Post(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). Body(pod). Do(). Into(result) <span class="hljs-keyword">return</span> }</code></pre>

Update

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// Update takes the representation of a pod and updates it. Returns the server's representation of the pod, and an error, if there is any.</span> <span class="hljs-keyword">func</span> (c *pods) Update(pod *v1.Pod) (result *v1.Pod, err error) { result = &v1.Pod{} err = c.client.Put(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). Name(pod.Name). Body(pod). Do(). Into(result) <span class="hljs-keyword">return</span> }</code></pre>

Delete

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// Delete takes name of the pod and deletes it. Returns an error if one occurs.</span> <span class="hljs-keyword">func</span> (c *pods) Delete(name <span class="hljs-typename">string</span>, options *meta_v1.DeleteOptions) error { <span class="hljs-keyword">return</span> c.client.Delete(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). Name(name). Body(options). Do(). Error() }</code></pre> <h3 id="23-接口的调用">2.3 接口的调用</h3>

示例:

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// 创建clientset实例</span> clientset, err := kubernetes.NewForConfig(config) <span class="hljs-comment">// 具体的调用</span> pods, err := clientset.CoreV1().Pods(<span class="hljs-string">""</span>).List(metav1.ListOptions{})</code></pre>

clientset实现了接口<code>Interface</code>,<code>Interface</code>是个接口组合,包含各个client的接口类型。例如<code>CoreV1()</code>方法对应的接口类型是<code>CoreV1Interface</code>。

以下是clientset的<code>CoreV1()</code>方法实现:

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// CoreV1 retrieves the CoreV1Client</span> <span class="hljs-keyword">func</span> (c *Clientset) CoreV1() corev1.CoreV1Interface { <span class="hljs-keyword">return</span> c.coreV1 }</code></pre>

该方法可以理解为是一个<code>构造函数</code>。构造函数的返回值类型是一个接口类型<code>CoreV1Interface</code>,而return的返回值是实现了该接口类型的结构体对象<code>c.coreV1</code>。

接口类型是一种特殊的类型,接口类型与结构体对象之间的关系好比变量类型与变量之间的关系。其中的结构体对象必须实现了该接口类型的所有方法。

所以clientset的<code>CoreV1()</code>方法实现是返回一个<code>CoreV1Client</code>结构体对象。该结构体对象实现了<code>CoreV1Interface</code>接口,该接口也是一个接口组合。

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> CoreV1Interface <span class="hljs-keyword">interface</span> { RESTClient() rest.Interface ComponentStatusesGetter ConfigMapsGetter EndpointsGetter EventsGetter LimitRangesGetter NamespacesGetter NodesGetter PersistentVolumesGetter PersistentVolumeClaimsGetter PodsGetter PodTemplatesGetter ReplicationControllersGetter ResourceQuotasGetter SecretsGetter ServicesGetter ServiceAccountsGetter }</code></pre>

而实现的<code>Pods()</code>方法是其中的<code>PodsGetter</code>接口。

<code>Pods()</code>同<code>CoreV1()</code>一样是个构造函数,构造函数的返回值类型是<code>PodInterface</code>接口,返回值是实现了<code>PodInterface</code>接口的<code>pods</code>结构体对象。

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">func</span> (c *CoreV1Client) Pods(namespace <span class="hljs-typename">string</span>) PodInterface { <span class="hljs-keyword">return</span> newPods(c, namespace) }</code></pre>

而<code>PodInterface</code>接口定义参考接口定义,<code>pods</code>对象实现了<code>PodInterface</code>接口的方法,具体参考接口的实现。

最终调用了<code>pods</code>对象的<code>List()</code>方法。

<pre class="prettyprint"><code class="language-go hljs ">pods, err := clientset.CoreV1().Pods(<span class="hljs-string">""</span>).List(metav1.ListOptions{})</code></pre>

即以上代码就是不断调用实现了某接口的结构体对象的构造函数,生成具体的结构体对象,再调用结构体对象的某个具体方法。

<h2 id="3-通用接口设计">3. 通用接口设计</h2> <h3 id="31-接口定义">3.1 接口定义</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// ProjectManager manage life cycle of Deployment and Resources</span> <span class="hljs-keyword">type</span> PodInterface <span class="hljs-keyword">interface</span> { Create(*v1.Pod) (*v1.Pod, error) Update(*v1.Pod) (*v1.Pod, error) UpdateStatus(*v1.Pod) (*v1.Pod, error) Delete(name <span class="hljs-typename">string</span>, options *meta_v1.DeleteOptions) error DeleteCollection(options *meta_v1.DeleteOptions, listOptions meta_v1.ListOptions) error Get(name <span class="hljs-typename">string</span>, options meta_v1.GetOptions) (*v1.Pod, error) List(opts meta_v1.ListOptions) (*v1.PodList, error) Watch(opts meta_v1.ListOptions) (watch.Interface, error) Patch(name <span class="hljs-typename">string</span>, pt types.PatchType, data []<span class="hljs-typename">byte</span>, subresources ...<span class="hljs-typename">string</span>) (result *v1.Pod, err error) PodExpansion }</code></pre> <h3 id="32-结构体定义">3.2 结构体定义</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// pods implements PodInterface</span> <span class="hljs-keyword">type</span> pods <span class="hljs-keyword">struct</span> { client rest.Interface ns <span class="hljs-typename">string</span> }</code></pre> <h3 id="33-构造函数">3.3 构造函数</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// newPods returns a Pods</span> <span class="hljs-keyword">func</span> newPods(c *CoreV1Client, namespace <span class="hljs-typename">string</span>) *pods { <span class="hljs-keyword">return</span> &pods{ client: c.RESTClient(), ns: namespace, } }</code></pre> <h3 id="34-结构体实现">3.4 结构体实现</h3>

List()

<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">// List takes label and field selectors, and returns the list of Pods that match those selectors.</span> <span class="hljs-keyword">func</span> (c *pods) List(opts meta_v1.ListOptions) (result *v1.PodList, err error) { result = &v1.PodList{} err = c.client.Get(). Namespace(c.ns). Resource(<span class="hljs-string">"pods"</span>). VersionedParams(&opts, scheme.ParameterCodec). Do(). Into(result) <span class="hljs-keyword">return</span> }</code></pre> <h3 id="35-接口调用">3.5 接口调用</h3> <pre class="prettyprint"><code class="language-go hljs ">pods, err := clientset.CoreV1().Pods(<span class="hljs-string">""</span>).List(metav1.ListOptions{})</code></pre> <h3 id="36-其他接口设计示例">3.6 其他接口设计示例</h3> <pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> XxxManager <span class="hljs-keyword">interface</span> { Create(args argsType) (*XxxStruct, error) Get(args argsType) (**XxxStruct, error) Update(args argsType) (*XxxStruct, error) Delete(name <span class="hljs-typename">string</span>, options *DeleleOptions) error } <span class="hljs-keyword">type</span> XxxManagerImpl <span class="hljs-keyword">struct</span> { Name <span class="hljs-typename">string</span> Namespace <span class="hljs-typename">string</span> kubeCli *kubernetes.Clientset } <span class="hljs-keyword">func</span> NewXxxManagerImpl (namespace, name <span class="hljs-typename">string</span>, kubeCli *kubernetes.Clientset) XxxManager { <span class="hljs-keyword">return</span> &XxxManagerImpl{ Name name, Namespace namespace, kubeCli: kubeCli, } } <span class="hljs-keyword">func</span> (xm *XxxManagerImpl) Create(args argsType) (*XxxStruct, error) { <span class="hljs-comment">//具体的方法实现</span> }</code></pre> 到此这篇关于“Golang系列(四)之面向接口编程”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
go语言使用之接口与继承的区别
Go语言基础之接口(面向对象编程下)
golang接口初解析
【Golang】go语言面向接口
golang基础教程
go struct 成员变量后面再加个字符串是什么意思?_Go语言的学习笔记(第十章) 接口...
工作好多年有可能还未真正了解接口和抽象类
关于Golang的介绍
Golang学习笔记(五):Go语言与C语言的区别
Golang系列(四)之面向接口编程

[关闭]
~ ~