2 回答
TA貢獻1799條經驗 獲得超9個贊
vAge不被視為僅是“值變量”,因為它是內存中存儲type值的已知位置age??v觀vAge只能作為它的價值,vAge.Set(10)是不是因為對自己的表現有效的,但由于vAge是可尋址的,該規范宣稱它的好來治療表達簡寫為“獲得vAge的地址,并調用設置該”編譯-time時,我們將能夠驗證這Set是為age或方法設置的一部分*age。您基本上允許編譯器在確定必要和可能的情況下對原始表達式進行文本擴展。
同時,編譯器將允許您調用,age(23).String()但不允許age(23).Set(10)。在這種情況下,我們正在使用type的不可尋址值age。由于說的無效&age(23),所以說的無效(&age(23)).Set(10); 編譯器不會進行該擴展。
查看Effective Go示例,您并沒有直接調用b.Write()我們知道b的完整類型的范圍。相反,您是制作的臨時副本,b并嘗試將其作為type的值傳遞出去interface io.Writer()。問題在于,實現Printf不會對傳入的對象一無所知,只是它承諾會知道如何接收Write(),因此它不知道在調用函數之前將abyteSlice轉換為a即可*ByteSlice。是否尋址的決定b必須在編譯時進行,PrintF其前提是其第一個參數知道如何在Write()不被引用的情況下進行接收。
您可能會認為,如果系統知道如何獲取age指針并將其轉換為age值,那么它應該可以執行相反的操作;但是,實際上并沒有意義。在Effective Go示例中,如果要傳遞b而不是&b,則將修改一個在PrintF返回后將不再存在的切片,這幾乎沒有用。在age上面的示例中,采用值23并用value覆蓋它實際上沒有任何意義10。在第一種情況下,讓編譯器停止并詢問程序員在移交時真正意味著什么是有意義的b。在后一種情況下,對于編譯器而言,拒絕修改常量值當然是有意義的。
此外,我不認為系統正在動態地將age的方法設置擴展為*age;。我的瘋狂猜測是,為每種基本類型的方法靜態地賦予了指針類型一個方法,該方法只是取消引用指針并調用該基本方法。自動執行此操作很安全,因為按值接收方法中的任何內容都無法更改指針。在另一個方向上,通過包裝被要求修改數據的方法來擴展一組要求修改數據的方法并不總是很有意義,因為它們所修改的數據此后不久就會消失。在某些情況下,這樣做確實是有意義的,但是這需要程序員明確地決定,并且編譯器停止并要求這樣做是有意義的。
tl; dr我認為,Effective Go中的段落可能需要重新措辭(盡管我可能太long了以至于無法勝任),但這是正確的。類型的指針*X實際上可以訪問的所有X方法,但“ X”不能訪問*X的。因此,當確定一個對象是否可以滿足給定的接口時,*X被允許滿足X可以實現的任何接口,但是反之則不成立。此外,即使X已知作用域中的類型變量在編譯時是可尋址的,所以編譯器可以將其轉換為*X-它會出于接口實現的目的而拒絕這樣做,因為這樣做可能沒有意義。 。
- 2 回答
- 0 關注
- 258 瀏覽
添加回答
舉報
