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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## **章面向對象編程** 1) Golang 也支持面向對象編程(OOP),但是和傳統的面向對象編程有區別,并不是純粹的面向對 象語言。所以我們說 Golang 支持面向對象編程特性是比較準確的。 2) Golang 沒有類(class),Go 語言的結構體(struct)和其它編程語言的類(class)有同等的地位,你可 以理解 Golang 是基于 struct 來實現 OOP 特性的。 3) Golang 面向對象編程非常簡潔,去掉了傳統 OOP 語言的繼承、方法重載、構造函數和析構函 數、隱藏的 this 指針等等 4) Golang 仍然有面向對象編程的繼承,封裝和多態的特性,只是實現的方式和其它 OOP 語言不 一樣,比如繼承 :Golang 沒有 extends 關鍵字,繼承是通過匿名字段來實現。 5) Golang 面向對象(OOP)很優雅,OOP 本身就是語言類型系統(type system)的一部分,通過接口 (interface)關聯,耦合性低,也非常靈活。后面同學們會充分體會到這個特點。也就是說在 Golang 中面 向接口編程是非常重要的特性。 **結構體與結構體變量(實例/對象)的關系示意圖** ![](https://img.kancloud.cn/b8/69/b869b84eef1c7c3bb1c7b793b2eb6d8b_745x294.png) 對上圖的說明 1) 將一類事物的特性提取出來(比如貓類), 形成一個新的數據類型, 就是一個結構體。 2) 通過這個結構體,我們可以創建多個變量(實例/對象) 3) 事物可以貓類,也可以是 Person , Fish 或是某個工具類。 ![](https://img.kancloud.cn/ca/ad/caadfe30bfc19c70618ac813a709bd77_876x92.png) **快速入門\-面向對象的方式(struct)解決養貓問題** ![](https://img.kancloud.cn/72/05/720504cafd537b207b38364b788adfc0_641x455.png) 1) 結構體是自定義的數據類型,代表一類事物. 2) 結構體變量(實例)是具體的,實際的,代表一個具體變量 **結構體變量(實例)在內存的布局(重要!)** ![](https://img.kancloud.cn/36/44/364468b79efb629f15ef8d59ca7e7497_805x246.png) **如何聲明結構體** ``` type 結構體名稱 struct { field1 type field2 type } ``` **字段/屬性** 1) 從概念或叫法上看: 結構體字段 \= 屬性 \= field (即授課中,統一叫字段) 2) 字段是結構體的一個組成部分,一般是基本數據類型、數組,也可是引用類型。比如我們前面定 義貓結構體 的 Name string 就是屬性 **注意事項和細節說明** 1) 字段聲明語法同變量,示例:字段名 字段類型 2) 字段的類型可以為:基本類型、數組或引用類型 3) 在創建一個結構體變量后,如果沒有給字段賦值,都對應一個零值(默認值),規則同前面講的 一樣: 布爾類型是 false ,數值是 0 ,字符串是 ""。 數組類型的默認值和它的元素類型相關,比如 score \[3\]int 則為\[0, 0, 0\] 指針,slice,和 map 的零值都是 nil ,即還沒有分配空間。 ![](https://img.kancloud.cn/d9/63/d96391079126f4d61170b00339c5d066_577x409.png) ![](https://img.kancloud.cn/49/14/49147b055554d23d2eaf6d6ec4656f5f_518x361.png) 4) 不同結構體變量的字段是獨立,互不影響,一個結構體變量字段的更改,不影響另外一個, 結構體 是值類型。 ![](https://img.kancloud.cn/a3/43/a343e339da0944cda602c8a0aa94316f_373x91.png) ![](https://img.kancloud.cn/5d/f1/5df11509f66ab2f1d4c6e82501e95464_542x221.png) ![](https://img.kancloud.cn/3e/ec/3eec7b2c7320695cf78758c9aa6c0591_419x246.png) #### **創建結構體變量和訪問結構體字段** 方式1-直接聲明 var 結構體名 結構體 方式2-{} var personPerson=Person{} ![](https://img.kancloud.cn/46/e3/46e364f54038d4b9f5181c7058392964_665x227.png) 方式3-& 案例:varperson\*Person=new(Person) ![](https://img.kancloud.cn/06/ee/06eec1f94d980bdb672fc06eacfac664_1046x453.png) 方式4-{} 案例:varperson\*Person=&Person{} ![](https://img.kancloud.cn/3a/43/3a43ab6a96b469e129b8ffa26238a658_816x434.png) **說明:** 1)第3種和第4種方式返回的是結構體指針。 2)結構體指針訪問字段的標準方式應該是:(\*結構體指針).字段名,比如(\*person).Name="tom" 3)但go做了一個簡化,也支持結構體指針.字段名,比如person.Name="tom"。更加符合程序員 使用的習慣,go編譯器底層對person.Name做了轉化(\*person).Name。 **struct類型的內存分配機制** ![](https://img.kancloud.cn/81/bd/81bdc1f2ff109315a8c9f05e7ceb9903_1037x594.png) ![](https://img.kancloud.cn/a9/ce/a9ce4fec0f4ac2157b2c16d541471cce_831x475.png) ![](https://img.kancloud.cn/62/aa/62aa6975f1cfce0877a1e431a1a93ad7_1094x761.png) ![](https://img.kancloud.cn/99/5e/995e6c42913cfa51c6a279c7d0115e5d_956x217.png) ![](https://img.kancloud.cn/d2/3e/d23e0976a48d5c49ab51c7cc3bc5dfed_1009x514.png) ![](https://img.kancloud.cn/91/d2/91d273283a0c03fd19d3554f75420f4d_872x263.png) **1)結構體的所有字段在內存中是連續的** **在下面的代碼中r1中有四個int 在內存中是連續的地址為16進制數那么相差8個數那么就相差8個字節逢8進一 好處是根據地址加減尋找非常快** ![](https://img.kancloud.cn/1b/67/1b679922cbd479eb2b46504b9d2c9c1a_708x18.png) ![](https://img.kancloud.cn/ce/f9/cef9232ac6548964e185eef85b434f39_617x700.png) ![](https://img.kancloud.cn/a1/dc/a1dc4b63d04d90eab0b83654c903eb3d_871x241.png) 2)結構體是用戶單獨定義的類型,和其它類型進行轉換時需要有完全相同的字段(名字、個數和類型) ![](https://img.kancloud.cn/5a/66/5a6649e51c50aa3ebb30231836163ec6_976x411.png) 3)結構體進行type重新定義(相當于取別名),Golang認為是新的數據類型,但是相互間可以強轉 ![](https://img.kancloud.cn/fe/60/fe60fccb36d6e8e544ff09e52ceb09a3_944x382.png) 4)struct的每個字段上,可以寫上一個tag,該tag可以通過反射機制獲取,常見的使用場景就是序列化和反序列化。 ![](https://img.kancloud.cn/c7/41/c741ee0041a0dbc673d1049acbae0369_918x215.png) ![](https://img.kancloud.cn/10/31/10312b5f42377af83fbb538e8860341c_746x466.png) ## **二:方法** Golang中的方法是作用在指定的數據類型上的(即:和指定的數據類型綁定),因此自定義類型,都可以有方法,而不僅僅是struct。 **方法的聲明和調用** ``` typeAstruct{ Numint } func(aA)test(){ fmt.Println(a.Num) } 對上面的語法的說明 1)func(aA)test(){}表示A結構體有一方法,方法名為test 2)(aA)體現test方法是和A類型綁定的 ``` ![](https://img.kancloud.cn/46/42/4642b758ab1ccce910a42a7c53bf7737_817x571.png) 對上面的總結 1)test方法和Person類型綁定 2)test方法只能通過Person類型的變量來調用,而不能直接調用,也不能使用其它類型變量來調用 ![](https://img.kancloud.cn/14/a0/14a0fb51c63955c7ba7e6bf1b5710f2e_589x116.png) 3)func(pPerson)test(){}...p表示哪個Person變量調用,這個p就是它的副本,這點和函數傳參非常相似 4)p這個名字,有程序員指定,不是固定,比如修改成person也是可以 方法的調用和傳參機制原理:(重要!) 方法的調用和傳參機制和函數基本一樣,不一樣的地方是方法調用時,會將調用方法的變量,當做實參也傳遞給方法。下面我們舉例說明。 ![](https://img.kancloud.cn/07/f1/07f1695850ccdf1143bc776b98ada002_821x425.png) 說明: 1)在通過一個變量去調用方法時,其調用機制和函數一樣 2)不一樣的地方時,變量調用方法時,該變量本身也會作為一個參數傳遞到方法(如果變量是值類型,則進行值拷貝,如果變量是引用類型,則進行地質拷貝) **方法的聲明(定義)** ``` func(receviertype)methodName(參數列表)(返回值列表){ 方法體 return返回值 } 1)參數列表:表示方法輸入 2)receviertype:表示這個方法和type這個類型進行綁定,或者說該方法作用于type類型 3)receivertype:type可以是結構體,也可以其它的自定義類型 4)receiver:就是type類型的一個變量(實例),比如:Person結構體的一個變量(實例) 5)返回值列表:表示返回的值,可以多個 6)方法主體:表示為了實現某一功能代碼塊 7)return語句不是必須的。 ``` **方法的注意事項和細節** 1)結構體類型是值類型,在方法調用中,遵守值類型的傳遞機制,是值拷貝傳遞方式 2)如程序員希望在方法中,修改結構體變量的值,可以通過結構體指針的方式來處理 ![](https://img.kancloud.cn/19/a5/19a50e719e541c6814236c6fd73ca20c_884x390.png) 3)Golang中的方法作用在指定的數據類型上的(即:和指定的數據類型綁定),因此自定義類型,都可以有方法,而不僅僅是struct,比如int,float32等都可以有方法 ![](https://img.kancloud.cn/14/5f/145fc46bd60f15d803976bd0e30f9171_851x467.png) 4)方法的訪問范圍控制的規則,和函數一樣。方法名首字母小寫,只能在本包訪問,方法首字母大寫,可以在本包和其它包訪問。\[講解\] 5)如果一個類型實現了String()這個方法,那么fmt.Println默認會調用這個變量的String()進行輸出 ![](https://img.kancloud.cn/8a/7b/8a7b62d026d73a25d452c59cd0d1df98_756x543.png) **方法和函數區別** 1)調用方式不一樣 函數的調用方式:函數名(實參列表) 方法的調用方式:變量.方法名(實參列表) 2)對于普通函數,接收者為值類型時,不能將指針類型的數據直接傳遞,反之亦然 ![](https://img.kancloud.cn/d4/4e/d44e16eff9a195a8609bce3b805cf1a9_939x738.png) 3)對于方法(如struct的方法),接收者為值類型時,可以直接用指針類型的變量調用方法,反過來同樣也可以 ![](https://img.kancloud.cn/4f/8d/4f8d0f0a284d328df81962e8a48cf9f2_929x343.png) ![](https://img.kancloud.cn/a7/51/a7514473bc5aa68213307d250f0f4602_882x326.png) 1)不管調用形式如何,真正決定是值拷貝還是地址拷貝,看這個方法是和哪個類型綁定. 2)如果是和值類型,比如(pPerson),則是值拷貝,如果和指針類型,比如是(p\*Person)則是地址拷貝。 **創建結構體變量時指定字段值** 方式1 ![](https://img.kancloud.cn/d0/7d/d07d366136f8baceb10cda418e24cc07_768x600.png) 方式2 ![](https://img.kancloud.cn/76/de/76de5295b4bdf15df1a1c3e9262c38c7_792x346.png)
                  <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>

                              哎呀哎呀视频在线观看