<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 經(jīng)典入門系列 27:組合取代繼承??

          共 5444字,需瀏覽 11分鐘

           ·

          2020-12-26 15:58

          點(diǎn)擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          歡迎來到 Golang 系列教程[1]的第 27 篇。

          Go 不支持繼承,但它支持組合(Composition)。組合一般定義為“合并在一起”。汽車就是一個(gè)關(guān)于組合的例子:一輛汽車由車輪、引擎和其他各種部件組合在一起。

          通過嵌套結(jié)構(gòu)體進(jìn)行組合

          在 Go 中,通過在結(jié)構(gòu)體內(nèi)嵌套結(jié)構(gòu)體,可以實(shí)現(xiàn)組合。

          組合的典型例子就是博客帖子。每一個(gè)博客的帖子都有標(biāo)題、內(nèi)容和作者信息。使用組合可以很好地表示它們。通過學(xué)習(xí)本教程后面的內(nèi)容,我們會(huì)知道如何實(shí)現(xiàn)組合。

          我們首先創(chuàng)建一個(gè) author 結(jié)構(gòu)體。

          package?main

          import?(
          ????"fmt"
          )

          type?author?struct?{
          ????firstName?string
          ????lastName??string
          ????bio???????string
          }

          func?(a?author)?fullName()?string?{
          ????return?fmt.Sprintf("%s?%s",?a.firstName,?a.lastName)
          }

          在上面的代碼片段中,我們創(chuàng)建了一個(gè) author 結(jié)構(gòu)體,author 的字段有 firstnamelastnamebio。我們還添加了一個(gè) fullName() 方法,其中 author 作為接收者類型,該方法返回了作者的全名。

          下一步我們創(chuàng)建 post 結(jié)構(gòu)體。

          type?post?struct?{
          ????title?????string
          ????content???string
          ????author
          }

          func?(p?post)?details()?{
          ????fmt.Println("Title:?",?p.title)
          ????fmt.Println("Content:?",?p.content)
          ????fmt.Println("Author:?",?p.author.fullName())
          ????fmt.Println("Bio:?",?p.author.bio)
          }

          post 結(jié)構(gòu)體的字段有 titlecontent。它還有一個(gè)嵌套的匿名字段 author。該字段指定 author 組成了 post 結(jié)構(gòu)體?,F(xiàn)在 post 可以訪問 author 結(jié)構(gòu)體的所有字段和方法。我們同樣給 post 結(jié)構(gòu)體添加了 details() 方法,用于打印標(biāo)題、內(nèi)容和作者的全名與簡介。

          一旦結(jié)構(gòu)體內(nèi)嵌套了一個(gè)結(jié)構(gòu)體字段,Go 可以使我們訪問其嵌套的字段,好像這些字段屬于外部結(jié)構(gòu)體一樣。所以上面第 11 行的 p.author.fullName() 可以替換為 p.fullName()。于是,details() 方法可以重寫,如下所示:

          func?(p?post)?details()?{
          ????fmt.Println("Title:?",?p.title)
          ????fmt.Println("Content:?",?p.content)
          ????fmt.Println("Author:?",?p.fullName())
          ????fmt.Println("Bio:?",?p.bio)
          }

          現(xiàn)在,我們的 authorpost 結(jié)構(gòu)體都已準(zhǔn)備就緒,我們來創(chuàng)建一個(gè)博客帖子來完成這個(gè)程序。

          package?main

          import?(
          ????"fmt"
          )

          type?author?struct?{
          ????firstName?string
          ????lastName??string
          ????bio???????string
          }

          func?(a?author)?fullName()?string?{
          ????return?fmt.Sprintf("%s?%s",?a.firstName,?a.lastName)
          }

          type?post?struct?{
          ????title???string
          ????content?string
          ????author
          }

          func?(p?post)?details()?{
          ????fmt.Println("Title:?",?p.title)
          ????fmt.Println("Content:?",?p.content)
          ????fmt.Println("Author:?",?p.fullName())
          ????fmt.Println("Bio:?",?p.bio)
          }

          func?main()?{
          ????author1?:=?author{
          ????????"Naveen",
          ????????"Ramanathan",
          ????????"Golang?Enthusiast",
          ????}
          ????post1?:=?post{
          ????????"Inheritance?in?Go",
          ????????"Go?supports?composition?instead?of?inheritance",
          ????????author1,
          ????}
          ????post1.details()
          }

          在 playground 上運(yùn)行[2]

          在上面程序中,main 函數(shù)在第 31 行新建了一個(gè) author 結(jié)構(gòu)體變量。而在第 36 行,我們通過嵌套 author1 來創(chuàng)建一個(gè) post。該程序輸出:

          Title:??Inheritance?in?Go
          Content:??Go?supports?composition?instead?of?inheritance
          Author:??Naveen?Ramanathan
          Bio:??Golang?Enthusiast

          結(jié)構(gòu)體切片的嵌套

          我們可以進(jìn)一步處理這個(gè)示例,使用博客帖子的切片來創(chuàng)建一個(gè)網(wǎng)站。:)

          我們首先定義 website 結(jié)構(gòu)體。請?jiān)谏鲜龃a里的 main 函數(shù)中,添加下面的代碼,并運(yùn)行它。

          type?website?struct?{
          ????????[]post
          }
          func?(w?website)?contents()?{
          ????fmt.Println("Contents?of?Website\n")
          ????for?_,?v?:=?range?w.posts?{
          ????????v.details()
          ????????fmt.Println()
          ????}
          }

          在你添加上述代碼后,當(dāng)你運(yùn)行程序時(shí),編譯器將會(huì)報(bào)錯(cuò),如下所示:

          main.go:31:9:?syntax?error:?unexpected?[,?expecting?field?name?or?embedded?type

          這項(xiàng)錯(cuò)誤指出了嵌套的結(jié)構(gòu)體切片 []post。錯(cuò)誤的原因是結(jié)構(gòu)體不能嵌套一個(gè)匿名切片。我們需要一個(gè)字段名。所以我們來修復(fù)這個(gè)錯(cuò)誤,讓編譯器順利通過。

          type?website?struct?{
          ????????posts?[]post
          }

          可以看到,我給帖子的切片 []post 添加了字段名 posts

          現(xiàn)在我們來修改主函數(shù),為我們的新網(wǎng)站創(chuàng)建一些帖子吧。

          修改后的完整代碼如下所示:

          package?main

          import?(
          ????"fmt"
          )

          type?author?struct?{
          ????firstName?string
          ????lastName??string
          ????bio???????string
          }

          func?(a?author)?fullName()?string?{
          ????return?fmt.Sprintf("%s?%s",?a.firstName,?a.lastName)
          }

          type?post?struct?{
          ????title???string
          ????content?string
          ????author
          }

          func?(p?post)?details()?{
          ????fmt.Println("Title:?",?p.title)
          ????fmt.Println("Content:?",?p.content)
          ????fmt.Println("Author:?",?p.fullName())
          ????fmt.Println("Bio:?",?p.bio)
          }

          type?website?struct?{
          ?posts?[]post
          }
          func?(w?website)?contents()?{
          ????fmt.Println("Contents?of?Website\n")
          ????for?_,?v?:=?range?w.posts?{
          ????????v.details()
          ????????fmt.Println()
          ????}
          }

          func?main()?{
          ????author1?:=?author{
          ????????"Naveen",
          ????????"Ramanathan",
          ????????"Golang?Enthusiast",
          ????}
          ????post1?:=?post{
          ????????"Inheritance?in?Go",
          ????????"Go?supports?composition?instead?of?inheritance",
          ????????author1,
          ????}
          ????post2?:=?post{
          ????????"Struct?instead?of?Classes?in?Go",
          ????????"Go?does?not?support?classes?but?methods?can?be?added?to?structs",
          ????????author1,
          ????}
          ????post3?:=?post{
          ????????"Concurrency",
          ????????"Go?is?a?concurrent?language?and?not?a?parallel?one",
          ????????author1,
          ????}
          ????w?:=?website{
          ????????posts:?[]post{post1,?post2,?post3},
          ????}
          ????w.contents()
          }

          在 playground 中運(yùn)行[3]

          在上面的主函數(shù)中,我們創(chuàng)建了一個(gè)作者 author1,以及三個(gè)帖子 post1post2post3。我們最后通過嵌套三個(gè)帖子,在第 62 行創(chuàng)建了網(wǎng)站 w,并在下一行顯示內(nèi)容。

          程序會(huì)輸出:

          Contents?of?Website

          Title:??Inheritance?in?Go
          Content:??Go?supports?composition?instead?of?inheritance
          Author:??Naveen?Ramanathan
          Bio:??Golang?Enthusiast

          Title:??Struct?instead?of?Classes?in?Go
          Content:??Go?does?not?support?classes?but?methods?can?be?added?to?structs
          Author:??Naveen?Ramanathan
          Bio:??Golang?Enthusiast

          Title:??Concurrency
          Content:??Go?is?a?concurrent?language?and?not?a?parallel?one
          Author:??Naveen?Ramanathan
          Bio:??Golang?Enthusiast

          本教程到此結(jié)束。祝你愉快。

          上一教程 - 結(jié)構(gòu)體取代類

          下一教程 - 多態(tài)[4]


          via: https://golangbot.com/inheritance

          作者:Nick Coghlan[5]譯者:Noluye[6]校對:polaris1119[7]

          本文由 GCTT[8] 原創(chuàng)編譯,Go 中文網(wǎng)[9] 榮譽(yù)推出

          參考資料

          [1]

          Golang 系列教程: https://studygolang.com/subject/2

          [2]

          在 playground 上運(yùn)行: https://play.golang.org/p/sskWaTpJgr

          [3]

          在 playground 中運(yùn)行: https://play.golang.org/p/gKaa0RbeAE

          [4]

          多態(tài): https://studygolang.com/articles/12681

          [5]

          Nick Coghlan: https://golangbot.com/about/

          [6]

          Noluye: https://github.com/Noluye

          [7]

          polaris1119: https://github.com/polaris1119

          [8]

          GCTT: https://github.com/studygolang/GCTT

          [9]

          Go 中文網(wǎng): https://studygolang.com/



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 49
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩电影一区 | 国产综合视频 | 免费清高视频一黄色情 | 天天干在线观看视频 | 中国一区二区操B视频 |