<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 經(jīng)典入門(mén)系列 12:可變參數(shù)函數(shù)

          共 4537字,需瀏覽 10分鐘

           ·

          2020-12-11 10:35

          點(diǎn)擊上方藍(lán)色“Go語(yǔ)言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          歡迎來(lái)到 Golang 系列教程第 12 部分。

          什么是可變參數(shù)函數(shù)

          可變參數(shù)函數(shù)是一種參數(shù)個(gè)數(shù)可變的函數(shù)。

          語(yǔ)法

          如果函數(shù)最后一個(gè)參數(shù)被記作 ...T,這時(shí)函數(shù)可以接受任意個(gè) T 類(lèi)型參數(shù)作為最后一個(gè)參數(shù)。

          請(qǐng)注意只有函數(shù)的最后一個(gè)參數(shù)才允許是可變的。

          通過(guò)一些例子理解可變參數(shù)函數(shù)如何工作

          你是否曾經(jīng)想過(guò) append 函數(shù)是如何將任意個(gè)參數(shù)值加入到切片中的。這樣 append 函數(shù)可以接受不同數(shù)量的參數(shù)。

          func?append(slice?[]Type,?elems?...Type)?[]Type

          上面是 append 函數(shù)的定義。在定義中 elems 是可變參數(shù)。這樣 append 函數(shù)可以接受可變化的參數(shù)。

          讓我們創(chuàng)建一個(gè)我們自己的可變參數(shù)函數(shù)。我們將寫(xiě)一段簡(jiǎn)單的程序,在輸入的整數(shù)列表里查找某個(gè)整數(shù)是否存在。

          package?main

          import?(
          ?"fmt"
          )

          func?find(num?int,?nums?...int)?{
          ?fmt.Printf("type?of?nums?is?%T\n",?nums)
          ?found?:=?false
          ?for?i,?v?:=?range?nums?{
          ??if?v?==?num?{
          ???fmt.Println(num,?"found?at?index",?i,?"in",?nums)
          ???found?=?true
          ??}
          ?}
          ?if?!found?{
          ??fmt.Println(num,?"not?found?in?",?nums)
          ?}
          ?fmt.Printf("\n")
          }
          func?main()?{
          ?find(89,?89,?90,?95)
          ?find(45,?56,?67,?45,?90,?109)
          ?find(78,?38,?56,?98)
          ?find(87)
          }

          在線運(yùn)行代碼[1]

          在上面程序中 func find(num int, nums ...int) ?中的 nums 可接受任意數(shù)量的參數(shù)。在 find 函數(shù)中,參數(shù) nums 相當(dāng)于一個(gè)整型切片。

          可變參數(shù)函數(shù)的工作原理是把可變參數(shù)轉(zhuǎn)換為一個(gè)新的切片。以上面程序中的第 22 行為例,find 函數(shù)中的可變參數(shù)是 89,90,95 。find 函數(shù)接受一個(gè) int 類(lèi)型的可變參數(shù)。因此這三個(gè)參數(shù)被編譯器轉(zhuǎn)換為一個(gè) int 類(lèi)型切片 int []int{89, 90, 95} 然后被傳入 find 函數(shù)。

          在第 10 行, for 循環(huán)遍歷 nums 切片,如果 num 在切片中,則打印 num 的位置。如果 num 不在切片中,則打印提示未找到該數(shù)字。

          上面代碼的輸出值如下,

          type?of?nums?is?[]int
          89?found?at?index?0?in?[89?90?95]

          type?of?nums?is?[]int
          45?found?at?index?2?in?[56?67?45?90?109]

          type?of?nums?is?[]int
          78?not?found?in??[38?56?98]

          type?of?nums?is?[]int
          87?not?found?in??[]

          在上面程序的第 25 行,find 函數(shù)僅有一個(gè)參數(shù)。我們沒(méi)有給可變參數(shù) nums ...int 傳入任何參數(shù)。這也是合法的,在這種情況下 nums 是一個(gè)長(zhǎng)度和容量為 0 的 nil 切片。

          給可變參數(shù)函數(shù)傳入切片

          下面例子中,我們給可變參數(shù)函數(shù)傳入一個(gè)切片,看看會(huì)發(fā)生什么。

          package?main

          import?(
          ?"fmt"
          )

          func?find(num?int,?nums?...int)?{
          ?fmt.Printf("type?of?nums?is?%T\n",?nums)
          ?found?:=?false
          ?for?i,?v?:=?range?nums?{
          ??if?v?==?num?{
          ???fmt.Println(num,?"found?at?index",?i,?"in",?nums)
          ???found?=?true
          ??}
          ?}
          ?if?!found?{
          ??fmt.Println(num,?"not?found?in?",?nums)
          ?}
          ?fmt.Printf("\n")
          }
          func?main()?{
          ?nums?:=?[]int{89,?90,?95}
          ?find(89,?nums)
          }

          在線運(yùn)行代碼[2]

          在第 23 行中,我們將一個(gè)切片傳給一個(gè)可變參數(shù)函數(shù)。

          這種情況下無(wú)法通過(guò)編譯,編譯器報(bào)出錯(cuò)誤 main.go:23: cannot use nums (type []int) as type int in argument to find

          為什么無(wú)法工作呢?原因很直接,find 函數(shù)的說(shuō)明如下,

          func?find(num?int,?nums?...int)

          由可變參數(shù)函數(shù)的定義可知,nums ...int 意味它可以接受 int 類(lèi)型的可變參數(shù)。

          在上面程序的第 23 行,nums 作為可變參數(shù)傳入 find 函數(shù)。前面我們知道,這些可變參數(shù)參數(shù)會(huì)被轉(zhuǎn)換為 int 類(lèi)型切片然后在傳入 find 函數(shù)中。但是在這里 nums 已經(jīng)是一個(gè) int 類(lèi)型切片,編譯器試圖在 nums 基礎(chǔ)上再創(chuàng)建一個(gè)切片,像下面這樣

          find(89,?[]int{nums})

          這里之所以會(huì)失敗是因?yàn)?nums 是一個(gè) []int類(lèi)型 而不是 int類(lèi)型。

          那么有沒(méi)有辦法給可變參數(shù)函數(shù)傳入切片參數(shù)呢?答案是肯定的。

          有一個(gè)可以直接將切片傳入可變參數(shù)函數(shù)的語(yǔ)法糖,你可以在在切片后加上 ... 后綴。如果這樣做,切片將直接傳入函數(shù),不再創(chuàng)建新的切片

          在上面的程序中,如果你將第 23 行的 find(89, nums) 替換為 find(89, nums...) ,程序?qū)⒊晒幾g并有如下輸出

          type?of?nums?is?[]int
          89?found?at?index?0?in?[89?90?95]

          下面是完整的程序供您參考。

          package?main

          import?(
          ?"fmt"
          )

          func?find(num?int,?nums?...int)?{
          ?fmt.Printf("type?of?nums?is?%T\n",?nums)
          ?found?:=?false
          ?for?i,?v?:=?range?nums?{
          ??if?v?==?num?{
          ???fmt.Println(num,?"found?at?index",?i,?"in",?nums)
          ???found?=?true
          ??}
          ?}
          ?if?!found?{
          ??fmt.Println(num,?"not?found?in?",?nums)
          ?}
          ?fmt.Printf("\n")
          }
          func?main()?{
          ?nums?:=?[]int{89,?90,?95}
          ?find(89,?nums...)
          }

          在線運(yùn)行代碼[3]

          不直觀的錯(cuò)誤

          當(dāng)你修改可變參數(shù)函數(shù)中的切片時(shí),請(qǐng)確保你知道你正在做什么。

          下面讓我們來(lái)看一個(gè)簡(jiǎn)單的例子。

          package?main

          import?(
          ?"fmt"
          )

          func?change(s?...string)?{
          ?s[0]?=?"Go"
          }

          func?main()?{
          ?welcome?:=?[]string{"hello",?"world"}
          ?change(welcome...)
          ?fmt.Println(welcome)
          }

          在線運(yùn)行代碼[4]

          你認(rèn)為這段代碼將輸出什么呢?如果你認(rèn)為它輸出 [Go world] 。恭喜你!你已經(jīng)理解了可變參數(shù)函數(shù)和切片。如果你猜錯(cuò)了,那也不要緊,讓我來(lái)解釋下為什么會(huì)有這樣的輸出。

          在第 13 行,我們使用了語(yǔ)法糖 ... 并且將切片作為可變參數(shù)傳入 change 函數(shù)。

          正如前面我們所討論的,如果使用了 ...welcome 切片本身會(huì)作為參數(shù)直接傳入,不需要再創(chuàng)建一個(gè)新的切片。這樣參數(shù) welcome 將作為參數(shù)傳入 change 函數(shù)

          change 函數(shù)中,切片的第一個(gè)元素被替換成 Go,這樣程序產(chǎn)生了下面的輸出值

          [Go?world]

          這里還有一個(gè)例子來(lái)理解可變參數(shù)函數(shù)。

          package?main

          import?(
          ?"fmt"
          )

          func?change(s?...string)?{
          ?s[0]?=?"Go"
          ?s?=?append(s,?"playground")
          ?fmt.Println(s)
          }

          func?main()?{
          ?welcome?:=?[]string{"hello",?"world"}
          ?change(welcome...)
          ?fmt.Println(welcome)
          }

          在線運(yùn)行代碼[5]

          我將把它作為一個(gè)練習(xí)留個(gè)你,請(qǐng)你指出上面的程序是如何運(yùn)行的 :) 。

          以上就是關(guān)于可變參數(shù)函數(shù)的介紹。感謝閱讀。歡迎您留下有價(jià)值的反饋和意見(jiàn)。祝您生活愉快。

          上一教程 - Array 和 Slice

          下一教程 - Maps[6]


          via: https://golangbot.com/variadic-functions/

          作者:Nick Coghlan[7]譯者:fengchunsgit[8]校對(duì):Noluye[9]

          本文由 GCTT[10] 原創(chuàng)編譯,Go 中文網(wǎng)[11] 榮譽(yù)推出

          參考資料

          [1]

          在線運(yùn)行代碼: https://play.golang.org/p/7occymiS6s

          [2]

          在線運(yùn)行代碼: https://play.golang.org/p/7occymiS6s

          [3]

          在線運(yùn)行代碼: https://play.golang.org/p/7occymiS6s

          [4]

          在線運(yùn)行代碼: https://play.golang.org/p/7occymiS6s

          [5]

          在線運(yùn)行代碼: https://play.golang.org/p/7occymiS6s

          [6]

          Maps: https://studygolang.com/articles/12251

          [7]

          Nick Coghlan: https://golangbot.com/about/

          [8]

          fengchunsgit: https://github.com/fengchunsgit

          [9]

          Noluye: https://github.com/Noluye

          [10]

          GCTT: https://github.com/studygolang/GCTT

          [11]

          Go 中文網(wǎng): https://studygolang.com/



          推薦閱讀


          福利

          我為大家整理了一份從入門(mén)到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門(mén)看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  综合激情网 | 国产成人在线综合豆花 | 大肠浣肠调教一区二区三区在线 | 自拍亚洲综合 | 亚洲黄色免费观看 |