2 回答

TA貢獻1871條經(jīng)驗 獲得超13個贊
shapesinterface 是*rect實現(xiàn)的東西,但它不是一個具體的 type *rect。就像任何接口一樣,它是一組方法,允許任何滿足它的類型通過,就像給它一個臨時的訪客貼紙以登上建筑物。
例如,如果有一只猴子(或者說它的價值是一只海豚),它可以行動并做人類所能做的一切,那么在 Go 的大樓里,他可以越過守衛(wèi),登上電梯。然而,這并不使他在基因上成為人類。
Go 是靜態(tài)類型的,這意味著即使沒有類型斷言或有意識地轉(zhuǎn)換類型,即使是具有相同底層類型的兩種類型也無法動態(tài)轉(zhuǎn)換或強制相互轉(zhuǎn)換。
var a int
type myInt int
var b myInt
a = 2
b = 3
b = a // Error! cannot use a (type int) as type myInt in assignment.
b = myInt(a) // This is ok.
和我一起想象一下這種情況:
type MyInt int
type YourInt int
type EveryInt interface {
addableByInt(a int) bool
}
func (i MyInt) addableByInt(a int) bool {
// whatever logic doesn't matter
return true
}
func (i YourInt) addableByInt(a int) bool {
// whatever logic doesn't matter
return true
}
func main() {
// Two guys want to pass as an int
b := MyInt(7)
c := YourInt(2)
// Do everything an `EveryInt` requires
// and disguise as one
bi := EveryInt(b)
ci := EveryInt(c)
// Hey, look we're the same! That's the closest
// we can get to being an int!
bi = ci // This is ok, we are EveryInt brotherhood
fmt.Println(bi) // bi is now 2
// Now a real int comes along saying
// "Hey, you two look like one of us!"
var i int
i = bi // Oops! bi has been made
// ci runs away at this point
}
現(xiàn)在回到你的場景——想象一下*circle實現(xiàn)shapes:
type circle struct {
Radius float64
}
func (c *circle) setWidth(w float64) {
c.Radius = w
}
*circle完全可以通過 asshapes但它沒有Width屬性,因為它不是*rect. 接口不能直接訪問底層類型的屬性,而只能通過實現(xiàn)的方法集來訪問。為了訪問屬性,需要在接口上進行類型斷言,以便實例成為具體類型:
var r *rect
// Verify `s` is in fact a `*rect` under the hood
if r, ok := s.(*rect); ok {
fmt.Println(r.Width)
}
這就是為什么像 Go 這樣的靜態(tài)類型語言總是比動態(tài)類型語言更快的核心,后者幾乎總是使用某種反射來為您動態(tài)處理類型強制。

TA貢獻1796條經(jīng)驗 獲得超4個贊
s 是 shape 接口的實現(xiàn)者,但在 for 循環(huán)中沒有輸入為 rect。如果您執(zhí)行類型斷言以強制 s 為具體類型,如下所示:
s.(*rect).Width
你會得到你想要的。
但是,您需要小心混合這樣的具體類型和接口。
- 2 回答
- 0 關(guān)注
- 162 瀏覽
添加回答
舉報