教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go语言之可变参函数的深度理解

go语言之可变参函数的深度理解

发布时间:2021-12-24   编辑:jiaochengji.com
教程集为您提供go语言之可变参函数的深度理解等资源,欢迎您收藏本站,我们将为您提供最新的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>

可变参函数的深度理解:

函数接收的参数数目都是确定的。而可变参数函数的参数数目是不确定的

如果一个函数的最后一个参数的表示形如:…Type,则该参数(形参)可以接受不同数目的参数(实参)

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">f</span><span class="token punctuation">(</span>elems <span class="token operator">...</span>Type<span class="token punctuation">)</span></code></pre>

<em>需要注意的一点,只允许最后一个参数是可变参数</em>

Go 中的一些内置函数都是可变参数函数:

<pre><code class="lang-go hljs">例如:<span class="token function">append</span><span class="token punctuation">(</span><span class="token punctuation">)</span>函数<span class="token punctuation">:</span> <span class="token keyword">func</span> <span class="token function">append</span><span class="token punctuation">(</span>slice <span class="token punctuation">[</span><span class="token punctuation">]</span>Type<span class="token punctuation">,</span> elems <span class="token operator">...</span>Type<span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>Type s <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">}</span> s <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">)</span> elems就是可变参数,可以接收任意数目的实参</code></pre>

可变参的原理:

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span>str1 <span class="token builtin">string</span><span class="token punctuation">,</span> s <span class="token operator">...</span><span class="token builtin">string</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>str1<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%T\n"</span><span class="token punctuation">,</span>s<span class="token punctuation">)</span> <span class="token comment">// %T 输出变量类型</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>s<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> str<span class="token operator">:=</span> <span class="token string">"net"</span> <span class="token function">test</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span><span class="token string">"Hello"</span><span class="token punctuation">,</span><span class="token string">"World"</span><span class="token punctuation">,</span><span class="token string">"Go"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//输出:</span> net <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token punctuation">[</span>Hello World Go<span class="token punctuation">]</span> </code></pre>

test()函数中,参数s是[]string类型的切片
可变参数函数的工作原理就是把可变参数转化成切片
调用test()函数时可变参数是Hello、World、Go,这三个参数被编译器转化成切片[]string{“Hello”,“World”,“Go”} ,然后被传入test()函数
另外,调用test()函数时候,可以不传可变参数,在 Go 语言里也是合法的,这种情况下,s是一个长度和容量都是 0 的 nil 切片
将切片传递给可变参数函数

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span>str1 <span class="token builtin">string</span><span class="token punctuation">,</span> s <span class="token operator">...</span><span class="token builtin">string</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>str1<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%T\n"</span><span class="token punctuation">,</span>s<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>s<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> slice <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">"Hello"</span><span class="token punctuation">,</span><span class="token string">"World"</span><span class="token punctuation">,</span><span class="token string">"Go"</span><span class="token punctuation">}</span> str <span class="token operator">:=</span> <span class="token string">"net"</span> <span class="token function">test</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span>slice<span class="token punctuation">)</span> <span class="token punctuation">}</span> 将切片slice传给可变参数函数<span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>,结果编译出错: cannot use slice <span class="token punctuation">(</span><span class="token keyword">type</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> as <span class="token keyword">type</span> <span class="token builtin">string</span> in argument to </code></pre>

由可变参数函数的定义可知,s …string 意味它可以接受 string 类型的可变参数。slice作为可变参数传入test()函数。前面我们知道,可变参数会被转换为 string 类型切片然后再传入test()函数中。但slice是一个 string 类型的切片,编译器试图通过下面这种方式在slice基础上再创建一个切片

<pre><code class="lang-go hljs"><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"net"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span>s<span class="token punctuation">}</span><span class="token punctuation">)</span> 之所以会失败,因为slice是<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span>类型,而不是<span class="token builtin">string</span>类型</code></pre>

解决方法:
Go 提供了将切片传入可变参数函数的语法糖:
直接在切片后加上…后缀。这样,切片将直接传入函数,不会再创建新的切片

<pre><code class="lang-go hljs"><span class="token function">test</span><span class="token punctuation">(</span>blog<span class="token punctuation">,</span>slice<span class="token operator">...</span><span class="token punctuation">)</span> <span class="token comment">//输出:</span> net <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token punctuation">[</span>Hello World Go<span class="token punctuation">]</span> </code></pre>

如果在函数中改变切片的值会发生什么呢?

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span>s <span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> s<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"net"</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%T\n"</span><span class="token punctuation">,</span>s<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>s<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> slice <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">"Hello"</span><span class="token punctuation">,</span><span class="token string">"World"</span><span class="token punctuation">,</span><span class="token string">"Go"</span><span class="token punctuation">}</span> <span class="token function">test</span><span class="token punctuation">(</span>slice<span class="token operator">...</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>slice<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//输出:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token punctuation">[</span>net World Go<span class="token punctuation">]</span> <span class="token punctuation">[</span>net World Go<span class="token punctuation">]</span> 使用了<span class="token operator">...</span>,切片本身会作为参数直接传入,不会再创建一个新的切片。 所以在<span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>函数中,第一个元素被替换成 net,会影响到<span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>函数的切片 </code></pre>

可以通过将数组转化成切片传递给可变参数函数:

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span>s <span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> s<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"net"</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%T\n"</span><span class="token punctuation">,</span>s<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>s<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> arr <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">"Hello"</span><span class="token punctuation">,</span><span class="token string">"World"</span><span class="token punctuation">,</span><span class="token string">"Go"</span><span class="token punctuation">}</span> <span class="token function">test</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token operator">...</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre> 到此这篇关于“go语言之可变参函数的深度理解”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
Go 语言到底适合干什么?
go run main.go 参数_Go语言入门:Hello world
go 语言学习历程
Go 语言包管理机制深入分析
Go 语言十年而立,Go2 蓄势待发
Go语言发展历史、核心、特性及学习路线
[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
兄弟连golang神技(1)-关于 Go 语言的介绍
想学一门新的编程语言?考虑一下Go (Golang)吧

[关闭]
~ ~