在下面的代碼片段中,我想知道當其內容仍未初始化時,究竟存儲在iPerson
中的數據是什麼:只有0字節的值?或者它實際上是一個隱藏的指針(當然也初始化爲0字節)?無論如何,在iPerson = person
究竟發生了什麼?Go中的接口變量究竟如何實現?
如果iPerson = person
使得person
副本,然後什麼時候會發生實施IPerson
但具有不同的尺寸/內存佔用的對象被分配到iPerson
?我明白iPerson
是一個存儲在堆棧上的變量,所以它的大小必須是固定的。這是否意味着堆實際上在引擎蓋下使用,所以iPerson
實際上是作爲指針實現的,但是作業仍然複製對象,如上面的代碼所示? 下面的代碼:
type Person struct{ name string }
type IPerson interface{}
func main() {
var person Person = Person{"John"}
var iPerson IPerson
fmt.Println(person) // => John
fmt.Println(iPerson) // => <nil> ...so looks like a pointer
iPerson = person // ...this seems to be making a copy
fmt.Println(iPerson) // => John
person.name = "Mike"
fmt.Println(person) // => Mike
fmt.Println(iPerson) // => John ...so looks like it wasn't a pointer,
// or at least something was definitely copied
}
(這個問題是我對我的回答why runtime error on io.WriterString?的確切事實的正確性有第二個想法的結果,所以我決定嘗試做一些調查,瞭解它是如何正是接口變量和任務對他們在工作圍棋)
編輯:收到了一些有用的答案後,我還是不解與此:
iPerson = person
iPerson = &person
-兩者都是合法的。但是,對我而言,這提出了編譯器爲什麼允許發生這種弱類型的問題?的上述一個含義是這樣的:
iPerson = &person
var person2 = iPerson.(Person) # panic: interface conversion: interface is *main.Person, not main.Person
而改變第一線修復它:
iPerson = person
var person2 = iPerson.(Person) # OK
...所以這是不可能的,以確定靜態iPerson
是否保存一指針或值;而且似乎任何東西都可以在運行時將其分配給它,而不會引發錯誤。爲什麼會做出這樣的設計決策?它的用途是什麼?它絕對不符合「類型安全」的理念。
讓我感到困惑的是,爲什麼Go允許'iPerson =&person'以及'iPerson = person'而不必改變'iPerson'的類型。它允許運行時類型的錯誤,而不是靜態捕獲。 Volker指出的這篇文章並沒有提到,甚至沒有提到。 –
如果您將結構視爲不可變的值,那麼按值傳遞它可能會很有意義。在實踐中,如果你定義了接收指針的方法,你可能不會混淆它們,因爲這些方法將無法訪問接口值中保存的值,所以不會混淆:http:// play .golang。org/p/E_8WjLS4S0 –
好的,你說在實踐中這不會成爲問題嗎?但我仍然認爲這是語言設計中的不雅,類型系統可以在這裏做得更好。 –