<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>

          []int 能轉(zhuǎn)換為 []interface 嗎?

          共 2495字,需瀏覽 5分鐘

           ·

          2021-09-01 12:28

          這個問題的答案是:不能。

          如果你還想知道更多的信息,就往下看。^_^

          有些時候我們希望有這樣的寫法:定義一個參數(shù)為 []interface 的函數(shù),在程序運行的過程中,傳入 []int 或其他類型的 slice,以此來達(dá)到少寫一些代碼的目的。譬如下面這個弱智的求 slice 和的例子:

          package main

          import "fmt"

          func sliceSum(inters []interface{}) (res interface{}) {
           nums := inters.([]int)

           sum := 0
           for _, num := range nums {
            sum += num
           }

           return sum
          }

          func main() {
           is := []int{78910}

           fmt.Println(sliceSum(is))
          }

          為了把這個程序?qū)懙酶ㄓ靡稽c,參數(shù)和返回值都是用的 interface 類型。編譯,會報錯:

          ./inter.go:6:16: invalid type assertion: inters.([]int) (non-interface type []interface {} on left)
          ./inter.go:19:22: cannot use is (type []int) as type []interface {} in argument to sliceSum

          第一個錯:不能將左邊的 []interface{} 轉(zhuǎn)換成右邊的 []int,因為 []interface 本身并不是 interface 類型,所以不能進(jìn)行斷言。

          第二個錯:sliceSum 函數(shù)不能接受 []int 類型的參數(shù),因為 []int 不是 []interface 類型。

          先把程序改成正確的:

          package main

          import "fmt"

          func sliceSum(inters []interface{}) (res interface{}){
           sum := 0
           for _, inter := range inters {
             sum += inter.(int)
           }

           return sum
          }

          func main() {
           is := []int{78910}
            
           iis := make([]interface{}, len(is))
           for i := 0; i < len(is); i++ {
             iis[i] = is[i]
           }

           fmt.Println(sliceSum(iis))
          }

          直接在循環(huán)的地方,對 inters 里的每個元素進(jìn)行斷言后再累加。

          再來研究下 Go 官方說的:[]int[]interface{} 內(nèi)存模型不一樣是什么意思。

          之前的 slice 文章講過,slice 底層有 3 個屬性:

          slice

          interface文章講過,interface 底層有兩個屬性:

          interface

          用 dlv 來調(diào)試,在關(guān)鍵地方打上斷點:

          image

          知道了 slice 地址后,打印出該地址處的數(shù)據(jù):

          x -fmt hex -len 24 0xc000055f30
          int slice

          第一行即 slice 底層的數(shù)組地址,0x04, 0x04 分別指的是長度、容量。0x07、0x08、0x09、0x0a 則是數(shù)組的四個元素。

          slice memory

          同樣的方法,來看看 interface slice 的內(nèi)存布局:

          interface slice

          其實也非常清楚,它的數(shù)據(jù)部分占 64 字節(jié):因為一個 interface{} 占用 16 個字節(jié),4 個元素所有是 64 個字節(jié)。

          interface memory

          最后,總結(jié)一下:Go 官方規(guī)定,[]int 不能轉(zhuǎn)換成 []interface{},因為兩者是不同的類型,[]interface 不是 interface 類型,且兩者的內(nèi)存布局并不相同。

          解決辦法就是泛型。那泛型的原理是什么呢?又是怎么實現(xiàn)的呢?問就是不知道~??

          注:本文內(nèi)容主要來自于 Eli 的博客[1]。

          參考資料

          [1]

          博客: https://eli.thegreenplace.net/2021/go-internals-invariance-and-memory-layout-of-slices/


          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  欧美老熟妇乱大交XXXXX 国产伦子伦一级A片在线 | 日韩婷婷 | 国产精品在线观看成人视频 | 免费 无码 国产在线 | 国产操操逼视频 |