第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 生成器函數(shù)來創(chuàng)建滿足接口的值

Go 生成器函數(shù)來創(chuàng)建滿足接口的值

Go
牧羊人nacy 2022-06-27 15:41:40
我試圖概括一些代碼中的值類型。我需要制作一大堆值,然后對它們進行操作。API 大致如下:type Foo interface {  A(string) error}func Run(foo_gen func () (Foo, error)) {  ...}另一方面,我有:type bar struct {  ...}func (bar Bar) A (s string) {  ...}func main() {  foo_gen := func () (bar, error) {  return bar{}, nil  }  mypackage.Run(foo_gen)}這失敗并顯示錯誤消息:cannot use foo_gen (type func () (bar, error)) as type func() (mypackage.Foo, error) in argument to mypackage.Run我還很陌生,所以我可能缺少一些基本的東西。我所期待的是編譯器會嘗試通過匹配方法類型(類似于記錄子類型關(guān)系)顯式bar轉(zhuǎn)換為Foo,但情況似乎并非如此?
查看完整描述

2 回答

?
HUWWW

TA貢獻1874條經(jīng)驗 獲得超12個贊

解釋可能令人驚訝,但實際上很簡單。

foo_gen被定義為func () (Foo, error),所以第一個返回值的類型Foo是 ,它是一個接口。

任何接口類型的值都是struct具有兩個指針的:指向該接口值中實際保存的具體值和指向(一些內(nèi)部對象表示)它的類型。關(guān)于如何實現(xiàn)接口值的經(jīng)典且非常好的(如果可能有點生疏)解釋是this。

您嘗試匹配我們剛剛討論的簽名的實際函數(shù)返回一個類型的值Bar作為它的第一個返回值。該類型是一種struct類型,它與原始簽名所期望的接口值無關(guān)。
換句話說,為了讓你的函數(shù)返回一個類型的值Bar滿足期望接口類型值的簽名,Foo編譯器必須生成代碼,將返回的值復(fù)制Bar到堆并從中合成一個值Foo。雖然可能是可行的,但這太含蓄了,否則可能會令人驚訝。

由于幾乎相同的原因,編譯器不允許將切片分配給[]T類型變量。[]interface{}


查看完整回答
反對 回復(fù) 2022-06-27
?
叮當(dāng)貓咪

TA貢獻1776條經(jīng)驗 獲得超12個贊

在類型級別上,這就是正在發(fā)生的事情。


問題是 go 編譯器無法將 a 提升func () (bar, error))到 afunc () (Foo, error)因為通常 go 值不是covariant。


這樣做的結(jié)果是有幾種方法可以解決這個問題。


一種是改變函數(shù)的返回類型:


foo_gen := func () (Foo, error) {

  return bar{}, nil

}

這是有效的,因為它能夠輕松地將bar{}值提升到一個Foo值。


如果我無法更改生成器函數(shù)(這也適用于通道等),另一種方法是將生成器包裝在另一個函數(shù)中:


bar_gen := func () (bar, error){

  return bar{}, nil

}

  

foo_gen := func() (Foo, error){

  foobar, err := bar_gen()

  return foobar, err

}


查看完整回答
反對 回復(fù) 2022-06-27
  • 2 回答
  • 0 關(guān)注
  • 112 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號