亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在設計和編寫庫時,什么時候應該使用指針作為參數,什么時候不應該?

在設計和編寫庫時,什么時候應該使用指針作為參數,什么時候不應該?

Go
陪伴而非守候 2021-12-07 16:02:00
對不起,如果我的問題看起來很愚蠢。我的背景是 PHP、Ruby、Python、Lua 和類似語言,我對現實生活中的指針沒有理解。從我在 Internet 上閱讀的內容以及我在提出的問題(何時是指針慣用語?)中得到的答復中,我了解到:復制大數據時應該使用指針。不是獲取整個對象層次結構,而是接收它的地址并訪問它。當您在結構上有一個修改它的函數時,必須使用指針。所以,指針似乎是一件很棒的事情:我應該總是將它們作為函數參數獲取,因為它們非常輕量級,如果我以某種方式最終不需要修改結構上的任何內容也沒關系。但是,憑直覺看這句話,我能感覺到它聽起來很毛骨悚然,但我不知道為什么。那么,作為正在設計結構及其相關函數或只是函數的人,我應該什么時候接收指針?我什么時候應該收到一個值,為什么?換句話說,我的NewAuthor方法&Author{ ... }什么時候應該返回,Author{ ... }什么時候應該返回?我的函數什么時候應該獲取一個指向作者的指針作為參數,什么時候它應該只獲取 type 的值(副本)Author?
查看完整描述

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 或其他沒有值類型的語言解決,那么這些性能上的細微差別并不重要。


一般來說,在學習語言時,將結構作為指針傳遞通常會做“正確的事情”。


對于所有其他類型或您希望保持為只讀的內容,請傳遞值。


該規則也有例外,但最好是在需求出現時學習這些規則,而不是試圖一次性重新定義您的世界。如果這是有道理的。


查看完整回答
反對 回復 2021-12-07
?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

只需您可以在任何您想要的地方使用指針,有時您不想更改您的數據。它可能代表抽象數據,您不想顯式復制數據。只需按值傳遞,讓編譯器完成它的工作。


查看完整回答
反對 回復 2021-12-07
  • 2 回答
  • 0 關注
  • 175 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號