通過 Go 理解指針與引用

前幾天,有同學在技術交流群裡問:指針與引用的區別?在群裡沒做太多解釋,回去找了篇 Steve Francia 大神關於「指針與引用」的文章,翻譯過來了!

包括 C、C++ 在內的一些語言支持指針。其他語言包括 C++、Java、Python、Ruby、Perl 和 PHP 都支持引用。從表面上看,引用和指針非常相似,它們都用來讓一個變量提供對另一個變量的訪問。由於兩者都提供了許多相同的功能,所以常常不清楚它們各自的內部機制有什麼不同。在本文中,我將說明指針和引用之間的區別。

為什麼這很重要

指針是 Go 語言的核心。大多數程序員都是在上面提到的一種語言的基礎上學習 Go 的。因此,理解指針和引用之間的區別對於理解 Go 至關重要。即使你使用過具有指針的語言,Go 對指針的實現也不同於 C 和 C++,因為它保留了引用的一些優秀屬性,同時保留了指針的功能。

本文的其餘部分旨在廣泛地討論引用的概念,而不是具體的實現。我們將使用 Go 作為指針的參考實現。

有什麼不同?

指針變量存儲的是另一個變量的地址。

引用變量指向另外一個變量。

為證明我們的觀點,用 C++ 舉個例子,它同時支持指針和引用。

第一行定義了變量 i;第 2 行定義了一個指向變量 i 內存地址的指針 ptr;第 3 行定義了一個指向變量 i 的引用 ref。

不僅操作符不同,而且使用的方法也不同。對於指針,必須使用 * 操作符來解引用。對於引用,不需要任何操作符。據瞭解,你傾向於使用引用的變量。

繼續我們的示例,下面兩行代碼都將把 i 的值更改為13。

你可能會問,如果我嘗試直接訪問變量 ptr 而不使用解引用。這就引出了指針和引用之間的第二個關鍵區別。指針可以重分配,而引用不能。換句話說,指針可以被分配另一個不同的地址。

看下 Go 的例子

到目前為止,你可以使用引用以一種相當類似的方式完成上述所有操作,而且通常使用更簡單的語法。

跟我一起,下面的例子將說明為什麼指針比引用更強大。

擴展下上面的函數:

你可以在這裡做個練習

理解引用和指針的關鍵在第二個例子。

如果我們使用引用處理,我們將無法通過 *ap 更改 b 的值,並將其反映在 *ap2 中。因為一旦你複製了一個引用,它們就各自獨立,沒有任何聯繫。然而,它們可能指向相同的變量,但你操作引用時將會改變它指向,而不是指向的值。

最後一個示例向你演示了更改一個指針的賦值以指向新地址。由於引用的限制,這是唯一可行的操作。


分享到:


相關文章: