2 回答

TA貢獻1825條經驗 獲得超4個贊
指針和值都需要權衡。
一般來說,指針會指向系統中的其他一些內存區域。無論是想要將指針傳遞給局部變量的函數的堆棧還是堆上的某個位置。
func A() {
i := 25
B(&i) // A sets up stack frame to call B,
// it copies the address of i so B can look it up later.
// At this point, i is equal to 30
}
func B(i *int){
// Here, i points to A's stack frame.
// For this to execute, I look at my variable "i",
// see the memory address it points to, then look at that to get the value of 25.
// That address may be on another page of memory,
// causing me to have to look it up from main memory (which is slow).
println(10 + (*i))
// Since I have the address to A's local variable, I can modify it.
*i = 30
}
每當我要查看它指向的數據時,指針都要求我不斷地取消引用它們。有時你不在乎。其他時候它很重要。這真的取決于應用程序。
如果該指針必須被多次取消引用(即:您傳入一個數字以在一堆不同的計算中使用),那么您將繼續支付成本。
與使用值相比:
func A() {
i := 25
B(i) // A sets up the stack frame to call B, copying in the value 25
// i is still 25, because A gave B a copy of the value, and not the address.
}
func B(i int){
// Here, i is simply on the stack. I don't have to do anything to use it.
println(10 + i)
// Since i here is a value on B's stack, modifications are not visible outside B's scpe
i = 30
}
由于沒有什么可以解引用,所以基本上可以自由使用局部變量。
如果這些值很大,則會發生傳遞值的不利方面,因為將數據復制到堆棧不是免費的。
對于 int 來說,這是一個清洗,因為指針是“int”大小的。對于結構或數組,您正在復制所有數據。
此外,堆棧上的大對象可以使堆棧變得特別大。Go 通過堆棧重新分配很好地處理了這個問題,但在高性能場景中,它可能對性能的影響太大。
還有一個數據安全方面(不能修改我通過值傳遞的東西),但我不認為這在大多數代碼庫中通常是一個問題。
基本上,如果您的問題已經可以通過 ruby、python 或其他沒有值類型的語言解決,那么這些性能上的細微差別并不重要。
一般來說,在學習語言時,將結構作為指針傳遞通常會做“正確的事情”。
對于所有其他類型或您希望保持為只讀的內容,請傳遞值。
該規則也有例外,但最好是在需求出現時學習這些規則,而不是試圖一次性重新定義您的世界。如果這是有道理的。
- 2 回答
- 0 關注
- 175 瀏覽
添加回答
舉報