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

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

使用戈朗嵌套結構(帶接口)

使用戈朗嵌套結構(帶接口)

Go
ITMISS 2022-10-04 19:55:59
兩句話,對于任何人來說,對于一個好的架構,我們應該使用接口,這些接口描述它的行為,這并不是一個秘密。Golang實現(xiàn)了這個想法,但他們的接口只有方法,但沒有字段。因此,使用它們的唯一方法是創(chuàng)建獲取器和設置器。但是有了這個,我在指針方面遇到了問題。例如:package mainimport "fmt"// Atype IA interface {    Foo() string}type A struct {    foo string}func (a *A) Foo() string {    return a.foo}// Btype IB interface {    A() *IA}type B struct {    a *IA}func (b *B) A() *IA {    return b.a}// mainfunc main() {    a := &A{"lol"}    b := &B{a} // cannot use a (type *A) as type *IA in field value: *IA is pointer to interface, not interface    foo := b.A().Foo() // b.A().Foo undefined (type *IA is pointer to interface, not interface)    fmt.Println(foo)}Ofc,我可以使用這樣的東西:(*(*b).A()).Foo()但這會那么好和合適嗎?我只想有像蟒蛇,js,ts這樣的行為:someObj.child1.child2.child2SomeMethod()也許我搞砸了指針,我只想知道使用嵌套對象的golang方法。
查看完整描述

1 回答

?
瀟瀟雨雨

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

這是絆倒的常見點,特別是對于剛接觸更高層次語言背景的人來說。以下是我如何保持直截了當:


首先,讓我們確定Go中的“接收器”(例如“方法”)是什么。就像Python一樣,一個方法實際上與一種類型相連的事實是語法糖??档氯麪栠@個例子:


package main


import "fmt"


type F struct {

  i int

}


func (f F)Foo() {

  fmt.Println(f.i)

}


func main() {

  F.Foo(F{1})

}

盡管可能令人驚訝,但此代碼已編譯并成功打印出預期的 .這是因為當您在類型上調(diào)用接收器時,真正發(fā)生的事情是該類型成為接收器的第一個參數(shù)。1


真的很快,讓我們也回顧一下指針,因為你似乎在評論中倒著說了。因此,需要明確的是:計算機程序中的任何值都存儲在內(nèi)存中,它在內(nèi)存中的地址也是可以存儲在變量中的值。我們將這些變量稱為“指向”值的指針。


如果我給一個函數(shù)一個值,他們只能在其函數(shù)的范圍內(nèi)更改該值。如果該值是內(nèi)存中的地址,則同樣如此。但是,我可以更改該地址的數(shù)據(jù),從而影響具有函數(shù)外部范圍的數(shù)據(jù)。


package main

import "fmt"


func f(i int) { i = i + 2 }


func pf(i *int) { *i = *i + 2 }


var i = 1


func main() {

  f(i)

  fmt.Println(i)

  pf(&i)

  fmt.Println(i)

}

打印輸出


1

3

f(i)更改其本地副本,但更改存儲在 中的地址處的數(shù)據(jù)。ipf(&i)i


我為什么經(jīng)歷這一切?因為這就是圍棋中的大多數(shù)接收器都是指針接收器的原因;因為您不想傳遞接收器的副本;您實際希望傳遞接收方的地址,以便它可以在自己的方法中改變自身。


請記住,接收器是語法糖:


func (t *Type)f(arg string)

等效于:


func f(t *Type, arg string)

希望這能清楚地說明為什么指針接收器如此普遍!好了,說到界面方面。


如您所知,接口定義了一組方法。如果類型定義了具有相同簽名的方法,則該類型將滿足該接口。對于值接收器或指針接收器,情況可能如此。


但是,一個類型不能同時具有具有相同名稱的值接收器和指針接收器:


func (t  T)F() {}

func (t *T)F() {} //method redeclared: T.F

因此,這意味著類型和指向該類型的指針不能具有相同的接收器;因此,類型或指向類型的指針實現(xiàn)接收器,但不是兩者。這一點很容易被忽視,因為go會自動轉換。所以這工作正常:



type T struct{}


func (t  T)F() {}

func (t *T)PF() {}


func main() {

 var t T 

 t.F()

 t.PF()

}

在 中,將自動轉換為指針。t.PF()t


但重申一下,類型和指向類型的指針不能同時定義相同的接收器。因此,如果滿足接口 ,則不滿足,反之亦然。TI*T


話雖如此,并且已經(jīng)理解了這一點,很容易想出一個簡單的規(guī)則:當你打算用指針滿足接口時,永遠不要將指針指向接口。


在代碼中,滿足 。所以你可以說你的“真的是*A*A'沒有任何意義。*AIAIA.  Thinking of it like this, you can see that taking the address of an IA that is actually an 


將它們放在一起,下面是定義兩個接口并鏈接調(diào)用。請注意,雖然指向我的結構的指針可能是滿足接口的值,但我永遠不需要獲取接口的地址。對于 和 接口的使用者來說,它們是類型還是指針接收器都不相關。IFIG


package main


import "fmt"


type IF interface {

  G() IG

}


type F struct {

  g IG

}


func (f *F)G() IG {

  return f.g

}


type IG interface {

  G()

}


type G struct{

  i int

}


func (g *G)G() {

  g.i++

  fmt.Println("Gee, ", g.i)

}


func main() {

  f := F{&G{1}}

  f.G().G()

}


需要指向接口的指針是非常罕見的,因此請確保您認為“接口由指針滿足”而不是“指向接口的指針”。


查看完整回答
反對 回復 2022-10-04
  • 1 回答
  • 0 關注
  • 106 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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