<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                地址:https://studygolang.com/articles/20062?fr=sidebar#google_vignette # Golang研學:在函數、方法、接口中用好指針類型 在大部分面向對象語言如C++、C#、Java,在函數傳參數時除了基礎值類型,對象是通過引用方式傳遞的。 **然而,在Go語言中,除了map、slice和chan,所有類型(包括struct)都是值傳遞的。** 那么,如何在**函數外**使用**函數內處理后**的變量呢?只能通過返回新變量嗎? **不,可以使用指針** 大部分面向對象語言都很少有用到指針的場景了,但是在Go語言中有大量的指針應用場景,要成為一名合格的Gopher,必須了解。 ## [](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FDawnGrp%2FDawnCode%2Ftree%2Fmaster%2Fcodes%2FgoPointer%23%25E6%25A6%2582%25E5%25BF%25B5)概念 每一個變量都會分配一塊內存,數據保存在內存中,內存有一個地址,就像門牌號,通過這個地址就可以找到里面存儲的數據。 指針就是保存這個內存地址的變量。 **在Go語言中,用`&`取得變量的地址** ~~~ //為了說明類型,我采用了顯性的變量定義方法,實際開發中更多的是用“:=”自動獲取類型變量類型 var mystr string = "Hello!" var mystrP *string = &mystr fmt.Println(mystrP) ~~~ 將以上代碼敲入main函數中,`go run`,打印出的內容就是`mystr`的內存地址。`mystrP`就是`mystr`的指針變量。 **用`*`取得指針變量指向的內存地址的值** 在之前的代碼的后面增加一句代碼: ~~~ fmt.Println(*mystrPointer) ~~~ `go run`運行后,可以看到打印出`mystr`的值“Hello!” **符號`*`也用做定義指針類型的關鍵字。** 例如: ~~~ var p *int ~~~ ## [](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FDawnGrp%2FDawnCode%2Ftree%2Fmaster%2Fcodes%2FgoPointer%23%25E6%258C%2587%25E9%2592%2588%25E5%25BA%2594%25E7%2594%25A8%25E5%259C%25BA%25E6%2599%25AF)指針應用場景 在其他OOP語言中,大多數情況是不需要花太多時間操作指針的,如Java、C#,對象的引用操作都已經交給了虛擬機和框架。而Go經常會用到指針。原因主要有3個: 1. Go語言中除了map、slice、chan外,其他類型在函數參數中都是值傳遞 2. Go語言不是面向對象的語言,很多時候實現結構體方法時需要用指針類型實現引用結構體對象 3. 指針也是一個類型,在實現接口`interface`時,結構體類型和其指針類型對接口的實現是不同的 接下來就分別介紹一下,期間會穿插一些簡單的代碼片段,您可以創建一個Go文件輸入代碼,運行體驗一下。 ### [](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FDawnGrp%2FDawnCode%2Ftree%2Fmaster%2Fcodes%2FgoPointer%23%25E5%2587%25BD%25E6%2595%25B0%25E4%25B8%25AD%25E4%25BC%25A0%25E9%2580%2592%25E6%258C%2587%25E9%2592%2588%25E5%258F%2582%25E6%2595%25B0)函數中傳遞指針參數 Go語言都是值傳遞,例如: ~~~ package main import "fmt" func main() { i := 0 f(i) fmt.Println(i) } func f(count int) { fmt.Println(count) count++ } ~~~ 結果: ~~~ 0 0 ~~~ `i`在執行前后沒有變化 如果希望被函數調用后,`i`的值產生變化,`f`函數的參數就應該改為`*int`類型。如: ~~~ func main() { i := 0 f(&i) fmt.Println(i) } func f(count *int) { fmt.Println(*count) (*count)++ } ~~~ 1. f定義參數用`*int`替代`int`,申明參數是一個int類型的指針類型 2. 調用函數時,不能直接傳遞int的變量`i`,而要傳遞用`&`取得`i`的地址 3. f函數內,參數`count`現在是指針了,不能直接打印,需要用`*`取出這個指針指向的地址里保存的值 4. `count`的取值+1. 5. 調用f函數,在主函數`main`里打印`i`。 可以看到結果 ~~~ 0 1 ~~~ `i`的值改變了。 ### [](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FDawnGrp%2FDawnCode%2Ftree%2Fmaster%2Fcodes%2FgoPointer%23struct%25E7%25BB%2593%25E6%259E%2584%25E4%25BD%2593%25E6%258C%2587%25E9%2592%2588%25E7%25B1%25BB%25E5%259E%258B%25E6%2596%25B9%25E6%25B3%2595)Struct結構體指針類型方法 Go語言中給結構體定義方法 ~~~ //定義一個結構體類型 type myStruct struct { Name string } //定義這個結構體的改名方法 func (m myStruct) ChangeName(newName string) { m.Name = newName } func main() { //創建這個結構體變量 mystruct := myStruct{ Name: "zeta", } //調用改名函數 mystruct.ChangeName("Chow") //沒改成功 fmt.Println(mystruct.Name) } ~~~ 這樣的方法不會改掉結構體變量內的字段值。 就算是結構體方法,如果不使用指針,方法內還是傳遞結構體的值。 現在我們改用指針類型定義結構體方法看看。 只修改`ChangeName`函數,用`*myStruct`類型替代`myStruct` ~~~ func (m *myStruct) ChangeName(newName string) { m.Name = newName } ~~~ 再運行一次,可以看到打印出來的名字改變了。 **當使用指針類型定義方法后,結構體類型的變量調用方法時會自動取得該結構體的指針類型并傳入方法。** ### [](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FDawnGrp%2FDawnCode%2Ftree%2Fmaster%2Fcodes%2FgoPointer%23%25E6%258C%2587%25E9%2592%2588%25E7%25B1%25BB%25E5%259E%258B%25E7%259A%2584%25E6%258E%25A5%25E5%258F%25A3%25E5%25AE%259E%25E7%258E%25B0)指針類型的接口實現 最近在某問答平臺回答了一個Gopher的問題,大致內容是問為什么不能用結構體指針類型實現接口方法? 看一下代碼 ~~~ //定義一個接口 type myInterface interface { ChangeName(string) SayMyName() } //定義一個結構體類型 type myStruct struct { Name string } //定義這個結構體的改名方法 func (m *myStruct) ChangeName(newName string) { m.Name = newName } func (m myStruct) SayMyName() { fmt.Println(m.Name) } //一個使用接口作為參數的函數 func SetName(s myInterface, name string) { s.ChangeName(name) } func main() { //創建這個結構體變量 mystruct := myStruct{ Name: "zeta", } SetName(mystruct, "Chow") mystruct.SayMyName() } ~~~ 這段代碼是無法編譯通過的,會提示 ~~~ cannot use mystruct (type myStruct) as type myInterface in argument to SetName: myStruct does not implement myInterface (ChangeName method has pointer receiver) ~~~ `myStruct`類型沒有實現接口方法`ChangeName`,也就是說`func (m *myStruct) ChangeName(newName string)`并不算實現了接口,因為它是`*myStruct`類型實現的,而不是`myStruct`。 改一改 在調用SetName時,用&mystruct 替代 mystruct: ~~~ SetName(&mystruct, "Chow") ~~~ 編譯運行,成功。 為什么結構體類型實現的接口該結構體的指針類型也算實現了,而指針類型實現的接口,不算是該結構體實現了接口呢? \*\* 原因是,結構體類型定義的方法可以被該結構體的指針類型調用;而結構體類型調用該指針類型的方法時是被轉換成指針,不是直接調用。\*\* 所以,`&mystruct`直接實現了接口定義的`ChangeName`和`SayMyName`兩個方法,而`mystruct`只能實現了`SayMyName`,`mystruct`調用`ChangeName`方法其實轉換成指針類型后調用的,不算實現了接口。 * * * 到此Go語言指針類型的應用介紹差不多了。 總結一下: 1. Go語言中指針非常常用,一定要掌握 2. Go語言除了map、slice、chan其他都是值傳遞,引用傳遞一定要用指針類型 3. 結構體類型定義方法要注意使用指針類型 4. 接口實現方法時,用指針類型實現的接口函數只能算是指針類型實現的,用結構體類型實現的方法也作為是指針類型實現。 歡迎大家一起討論、學習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>

                              哎呀哎呀视频在线观看