<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## 什么是指針 程序運行時的數據是存放在內存中的,而內存會被抽象為一系列具有連續編號的存儲空間,那么每一個存儲在內存中的數據都會有一個編號,這個編號就是內存地址。有了這個內存地址就可以找到這個內存中存儲的數據,而內存地址可以被賦值給一個指針。 可以總結為:在編程語言中,指針是一種數據類型,用來存儲一個內存地址,該地址指向存儲在該內存中的對象。這個對象可以是字符串、整數、函數或者你自定義的結構體。 ## 指針的聲明和定義 在 Go 語言中,獲取一個變量的指針非常容易,使用取地址符 & 就可以,比如下面的例子: ``` func main() { strVal := "PHP is the best language in the world!" strPtr := &strPtr//取地址 fmt.Println("strPtrr變量的值為:",strPtrr) fmt.Println("strPtr變量的內存地址為:",strPtr) } ``` > 指針類型非常廉價,只占用 4 個或者 8 個字節的內存大小。 以上示例中 strPtr 指針的類型是 *string,用于指向 string 類型的數據。在 Go 語言中使用類型名稱前加 `*` 的方式,即可表示一個對應的指針類型。比如 int 類型的指針類型是 *int,float64 類型的指針類型是 *float64,自定義結構體 A 的指針類型是 *A。總之,指針類型就是在對應的類型前加 * 號。 此外,除了可以通過簡短聲明的方式聲明一個指針類型的變量外,也可以使用 var 關鍵字聲明, `var intP *int ` > 通過 var 聲明的指針變量是不能直接賦值和取值的,因為這時候它僅僅是個變量,還沒有對應的內存地址,它的值是 nil。 和普通類型不一樣的是,指針類型還可以通過內置的 new 函數來聲明,如下所示: ``` intP := new(int) ``` 內置的 new 函數有一個參數,可以傳遞類型給它。它會返回對應的指針類型,比如上述示例中會返回一個 *int 類型的 intP。 ## 指針的操作 在 Go 語言中指針的操作無非是兩種:一種是獲取指針指向的值,一種是修改指針指向的值。 要獲取指針指向的值,只需要在指針變量前加 * 號即可: ``` strVal := *strPtr fmt.Println("strPtr指針指向的值為:", strVal) ``` 修改指針指向的值也非常簡單 ``` *strPtr = "hello world" //修改指針指向的值 fmt.Println("strPtr指針指向的值為:",*strPtr) // hello world fmt.Println("strPtr變量的值為:", str) // hello world ``` 通過打印結果可以看到,不光 strPtr 指針指向的值被改變了,變量 strVal 的值也被改變了,這就是指針的作用。因為變量 strVal 存儲數據的內存就是指針 strPtr 指向的內存,這塊內存被 strPtr 修改后,變量 strVal 的值也被修改了。 通過 var 關鍵字直接定義的指針變量是不能進行賦值操作的,因為它的值為 nil,也就是還沒有指向的內存地址。比如下面的示例: ``` var intP *int *intP =10 ``` 運行的時候會提示 `invalid memory address or nil pointer dereference`。這時候該怎么辦呢?其實只需要通過 new 函數給它分配一塊內存就可以了,如下所示: ``` var intPtr *int = new(int) 或者 //intPtr := new(int) ``` ## 指針接收者 對于是否使用指針類型作為接收者,有以下幾點參考: 1. 如果接收者類型是 map、slice、channel 這類引用類型,不使用指針; 2. 如果需要修改接收者,那么需要使用指針; 3. 如果接收者是比較大的類型,可以考慮使用指針,因為內存拷貝廉價,所以效率高。 ## 什么情況下使用指針 從以上指針的詳細分析中,可以總結出指針的兩大好處: 1. 可以修改指向數據的值; 2. 在變量賦值,參數傳值的時候可以節省內存。 不過 Go 語言作為一種高級語言,在指針的使用上還是比較克制的。它在設計的時候就對指針進行了諸多限制,比如指針不能進行運行,也不能獲取常量的指針。所以在思考是否使用時,我們也要保持克制的心態。 使用指針的建議: 1. 不要對 map、slice、channel 這類引用類型使用指針; 2. 如果需要修改方法接收者內部的數據或者狀態時,需要使用指針; 3. 如果需要修改參數的值或者內部數據時,也需要使用指針類型的參數; 4. 如果是比較大的結構體,每次參數傳遞或者調用方法都要內存拷貝,內存占用多,這時候可以考慮使用指針; 5. 像 int、bool 這樣的小數據類型沒必要使用指針; 6. 如果需要并發安全,則盡可能地不要使用指針,使用指針一定要保證并發安全; 7. 指針最好不要嵌套,也就是不要使用一個指向指針的指針,雖然 Go 語言允許這么做,但是這會使你的代碼變得異常復雜。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看