php小編香蕉在這篇文章中將為大家介紹一個(gè)重要的概念:“稍后將新值分配給 go 中接口的底層對(duì)象”。這個(gè)概念在Go語(yǔ)言中非常常見(jiàn),它允許我們?cè)谶\(yùn)行時(shí)動(dòng)態(tài)地改變接口的底層對(duì)象,從而實(shí)現(xiàn)更靈活的編程。通過(guò)這種方式,我們可以在不改變接口定義的情況下,替換接口的具體實(shí)現(xiàn),從而實(shí)現(xiàn)代碼的擴(kuò)展和靈活性。在接下來(lái)的文章中,我們將詳細(xì)討論這個(gè)概念的原理和用法。
問(wèn)題內(nèi)容
我試圖在下面的代碼中為接口的底層結(jié)構(gòu)分配新值。但它保留了舊的價(jià)值觀。下面是示例代碼。
package main import ( "fmt" "math" ) type Shape interface { Area() float64 } type Circle struct { Radius float64 Name string } func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius } type Rectangle struct { Length float64 Width float64 Name string } func (r Rectangle) Area() float64 { return r.Length * r.Width } func assignRadius(s Shape, radius float64, name string) { switch s := s.(type) { case Circle: s.Radius = radius s.Name = name case Rectangle: s.Length = radius s.Name = name } } func main() { var s Shape c := Circle{Radius: 0, Name: "My Circle"} s = c fmt.Println(s.Area()) fmt.Println(c.Radius) fmt.Println(c.Name) assignRadius(s, 10, "My New Circle") fmt.Println(c.Radius) fmt.Println(c.Name) }
登錄后復(fù)制
shape
的類型在 assignradius
中事先未知。我知道這與指針有關(guān)。但想不通。
解決方法
接口變量 s
包含形狀值的副本。要像您嘗試的那樣修改它,它必須包含指向該形狀的指針:
var s shape c := circle{radius: 0, name: "my circle"} s = &c
登錄后復(fù)制
并且在修改它們的函數(shù)中,您必須鍵入斷言指針值:
func assignRadius(s Shape, radius float64, name string) { switch s := s.(type) { case *Circle: s.Radius = radius s.Name = name case *Rectangle: s.Length = radius s.Name = name }
登錄后復(fù)制