教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go学习笔记(13)Go接口

Go学习笔记(13)Go接口

发布时间:2021-12-22   编辑:jiaochengji.com
教程集为您提供Go学习笔记(13)Go接口等资源,欢迎您收藏本站,我们将为您提供最新的Go学习笔记(13)Go接口资源
<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>

<h3>文章目录</h3> <ul><li>Go的接口</li><li>接口的定义和使用</li><li>在接口中内嵌接口</li><li>接口转换</li><li>空接口</li><li>类型断言</li></ul>

<h1>Go的接口</h1>

    Go的接口定义了一组方法(方法集),但不包含这些方法的具体实现。接口提供了一种方式来说明某类对象具有的行为,它的主要特点如下:

<ul><li>接口实际上就是一组方法声明的集合,没有具体实现,没有字段属性</li><li>某个类型只要实现了某个接口的所有方法,就实现了该接口,不需要显示声明实现了什么接口</li><li>接口可以嵌入其它的接口</li></ul><h1>接口的定义和使用</h1>

    定义接口的形式:

<pre><code class="lang-go hljs"><span class="token keyword">type</span> InterfaceName <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Method1</span><span class="token punctuation">(</span>param_list<span class="token punctuation">)</span> return_type <span class="token function">Method2</span><span class="token punctuation">(</span>param_list<span class="token punctuation">)</span> return_type <span class="token punctuation">}</span> </code></pre>

    下面是一个接口使用的实例,定义了一个<code>Shaper</code>的接口,它包含了<code>Area()</code>和<code>Perimeter</code>两个方法;再定义了一个<code>Square</code>类型,它实现了上述具体两个方法,从而继承了接口。在主程序中,就可以创建一个<code>Square</code>类型的变量赋值给接口<code>Shaper</code>

<pre><code class="lang-go hljs"><span class="token comment">//定义接口</span> <span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token comment">//定义类型正方形</span> <span class="token keyword">type</span> Square <span class="token keyword">struct</span> <span class="token punctuation">{</span> side <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token comment">//实现接口中的方法Area</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> sq<span class="token punctuation">.</span>side <span class="token punctuation">}</span> <span class="token comment">//实现接口中的方法Perimeter</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> <span class="token number">4</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> sq Shaper sq <span class="token operator">=</span> Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>sq<span class="token punctuation">.</span><span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre>

    要注意的是,当对象赋值给接口时(<code>sq=Square{side:2,}</code>),会对对象进行拷贝,再赋值给接口,接口中保存的是指向这个拷贝的地址指针。为了性能考虑,我们也可以将对象的指针赋值给接口,这样就不需要拷贝整个原始对象,只拷贝对象地址,地址还是指向原来的对象。上面的代码可以改成:

<pre><code class="lang-go hljs"><span class="token comment">//定义接口</span> <span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token comment">//定义类型正方形</span> <span class="token keyword">type</span> Square <span class="token keyword">struct</span> <span class="token punctuation">{</span> side <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token comment">//实现接口中的方法Area</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq <span class="token operator">*</span>Square<span class="token punctuation">)</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> sq<span class="token punctuation">.</span>side <span class="token punctuation">}</span> <span class="token comment">//实现接口中的方法Perimeter</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq <span class="token operator">*</span>Square<span class="token punctuation">)</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> <span class="token number">4</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> sq Shaper sq <span class="token operator">=</span> <span class="token operator">&</span>Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

    此外,还需要注意到几点:

<ul><li>多个类型可以实现同一个接口</li><li>实现某个接口的类型除了实现接口要求实现的方法外,还可以有其它的方法</li><li>一个类型可以实现多个接口</li></ul><h1>
在接口中内嵌接口</h1>

    在Go接口的声明中同样可以嵌入一个接口,实现该外层接口的类型同样需要实现内嵌接口声明的方法

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> infoPrint <span class="token comment">//嵌入接口</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> infoPrint <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">PrintInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//计算面积</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> sq<span class="token punctuation">.</span>side <span class="token punctuation">}</span> <span class="token comment">//计算周长</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> <span class="token number">4</span> <span class="token punctuation">}</span> <span class="token comment">//实现内嵌接口的方法</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">PrintInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"我是一个正方形"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> sq Shaper sq <span class="token operator">=</span> Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <h1>
接口转换</h1>

    不同的接口之间可以进行转换,转换的原则是大接口转小接口,即将拥有内嵌子接口的接口转换为内嵌子接口

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> infoPrint <span class="token comment">//嵌入接口</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> infoPrint <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">PrintInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//省略方法实现</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> sq Shaper sq <span class="token operator">=</span> Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> ip infoPrint ip <span class="token operator">=</span> <span class="token function">infoPrint</span><span class="token punctuation">(</span>sq<span class="token punctuation">)</span> <span class="token comment">//这里将Shaper转换为inforPrint</span> ip<span class="token punctuation">.</span><span class="token function">PrintInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h1>
空接口</h1>

    如果一个接口中不含任何的方法,那么该接口是个空接口,所有的类型都实现了空接口,它相当于所有类型的基类,类似于Java中的<code>Object</code>类

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Empty <span class="token keyword">interface</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> </code></pre>

    可以给一个空接口的变量赋值任何类型

<h1>
类型断言</h1>

    一个接口类型的变量中可能包含着不同实际类型的值(实现接口的可以有不同的类型),当我们需要判断接口变量中的实际类型时,可以使用类型断言来检测
    假设<code>i</code>是一个接口变量,<code>T</code>是某个具体实现该接口的类型,那么可以使用下面的语句来检测<code>i</code>是否为类型<code>T</code>:

<pre><code class="lang-go hljs">s<span class="token punctuation">,</span> ok <span class="token operator">:=</span> i<span class="token punctuation">.</span><span class="token punctuation">(</span>T<span class="token punctuation">)</span> </code></pre>

    当接口变量<code>i</code>的实际类型是<code>T</code>时,<code>s</code>是<code>i</code>转换到类型<code>T</code>的值,<code>ok</code>的值是<code>true</code>;当接口变量<code>i</code>的实际类型不是<code>T</code>时,<code>s</code>是类型<code>T</code>的零值,<code>ok</code>是<code>false</code>。下面是一段检测接口类型的实例:

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> Square <span class="token keyword">struct</span> <span class="token punctuation">{</span> side <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token comment">//计算面积</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> sq<span class="token punctuation">.</span>side <span class="token punctuation">}</span> <span class="token comment">//计算周长</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> <span class="token number">4</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> sq <span class="token operator">:=</span> Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token function">isShape</span><span class="token punctuation">(</span>sq<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//判断接口中的数据类型</span> <span class="token keyword">func</span> <span class="token function">isShape</span><span class="token punctuation">(</span>s Shaper<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> sp<span class="token punctuation">,</span> ok <span class="token operator">:=</span> s<span class="token punctuation">.</span><span class="token punctuation">(</span>Square<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>sp<span class="token punctuation">,</span> <span class="token string">"is a shaper"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"none"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

    接口变量的类型也可以用一种<code>type-switch</code>的形式去检测:

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Shaper <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> Square <span class="token keyword">struct</span> <span class="token punctuation">{</span> side <span class="token builtin">float64</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> sq<span class="token punctuation">.</span>side <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>sq Square<span class="token punctuation">)</span> <span class="token function">Perimeter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">float64</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> sq<span class="token punctuation">.</span>side <span class="token operator">*</span> <span class="token number">4</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> sq <span class="token operator">:=</span> Square<span class="token punctuation">{</span> side<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token function">whatType</span><span class="token punctuation">(</span>sq<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">whatType</span><span class="token punctuation">(</span>s <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">switch</span> v <span class="token operator">:=</span> s<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token keyword">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> Square<span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">,</span> <span class="token string">"is a square"</span><span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token builtin">int</span><span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">,</span> <span class="token string">"is a square"</span><span class="token punctuation">)</span> <span class="token keyword">default</span><span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"none"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

    在函数<code>whatType</code>中,对接口变量的类型进行检测,函数传入的是一个空接口类型的参数,<code>v = s.(type)</code>得到变量<code>s</code>的具体类型,然后对<code>case</code>中列举的类型进行匹配,如果被检测的类型没有在<code>case</code>语句列举的类型中,就会执行<code>default</code>语句。但注意<code>type-switch</code>中不允许使用<code>fallthrough</code>

到此这篇关于“Go学习笔记(13)Go接口”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
Golang笔记:语法,并发思想,web开发,Go微服务相关
go语言学习笔记(十三)——接口类型
go语言学习笔记(第3章)—面向对象编程
Golang学习笔记(五):Go语言与C语言的区别
2018年最全Go语言教程零基础入门到进阶实战视频
Go学习笔记:接口实现与指针
go run main.go 参数_Go语言入门:Hello world
Sublime Text 3配置Go语言开发环境
go 语言学习历程

[关闭]
~ ~