Go語(yǔ)言開(kāi)發(fā)(四)、Go語(yǔ)言面向?qū)ο?創(chuàng)新互聯(lián)

Go語(yǔ)言開(kāi)發(fā)(四)、Go語(yǔ)言面向?qū)ο?/h2>

一、結(jié)構(gòu)體和方法

1、結(jié)構(gòu)體的定義

在結(jié)構(gòu)體中可以為不同項(xiàng)定義不同的數(shù)據(jù)類(lèi)型。
結(jié)構(gòu)體是由一系列具有相同類(lèi)型或不同類(lèi)型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合。
結(jié)構(gòu)體定義需要使用type和struct語(yǔ)句。struct語(yǔ)句定義一個(gè)新的數(shù)據(jù)類(lèi)型,結(jié)構(gòu)體有中有一個(gè)或多個(gè)成員。type語(yǔ)句設(shè)定了結(jié)構(gòu)體的名稱。結(jié)構(gòu)體的格式如下:

成都創(chuàng)新互聯(lián)網(wǎng)站建設(shè)由有經(jīng)驗(yàn)的網(wǎng)站設(shè)計(jì)師、開(kāi)發(fā)人員和項(xiàng)目經(jīng)理組成的專業(yè)建站團(tuán)隊(duì),負(fù)責(zé)網(wǎng)站視覺(jué)設(shè)計(jì)、用戶體驗(yàn)優(yōu)化、交互設(shè)計(jì)和前端開(kāi)發(fā)等方面的工作,以確保網(wǎng)站外觀精美、成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站易于使用并且具有良好的響應(yīng)性。
type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

結(jié)構(gòu)體類(lèi)型用于變量聲明的語(yǔ)法格式如下:
variable_name := structure_variable_type {value1, value2...valuen}
二叉樹(shù)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)定義如下:

package main

import "fmt"

type TreeNode struct{
   Value int
   Left,Right *TreeNode
}

func main() {
   var root TreeNode
   fmt.Println(root)
}

2、結(jié)構(gòu)體成員的訪問(wèn)

如果要訪問(wèn)結(jié)構(gòu)體成員,需要使用點(diǎn)號(hào)(.)操作符,格式為:"結(jié)構(gòu)體.成員名"。
結(jié)構(gòu)體類(lèi)型變量使用struct關(guān)鍵字定義,實(shí)例如下:

func main() {
   var root TreeNode
   root.Value = 0
   root.Left = &TreeNode{Value:1}
   root.Right = &TreeNode{2,nil,nil}
   root.Left.Left = &TreeNode{Value:3}
   root.Print()
}

3、結(jié)構(gòu)體方法的定義

結(jié)構(gòu)體方法定義在結(jié)構(gòu)體作用域外,需要在函數(shù)聲明中指定接收者。

func (variable_name struct_variable_type) function_name(parameters){
    //函數(shù)體
}

如二叉樹(shù)節(jié)點(diǎn)的遍歷打印函數(shù)如下:

func (node TreeNode) Print(){
      fmt.Println(node.Value, " ")
}

func (node *TreeNode)traverse(){
   if node != nil{
      //遞歸遍歷左子樹(shù)
      node.Left.traverse()
      node.Print()
      //遞歸遍歷右子樹(shù)
      node.Right.traverse()
   }
}

4、結(jié)構(gòu)體指針

如果結(jié)構(gòu)體的方法中需要對(duì)結(jié)構(gòu)體成員的值進(jìn)行修改,必須使用結(jié)構(gòu)體指針作為方法的接收者。如果結(jié)構(gòu)體過(guò)大也要考慮使用結(jié)構(gòu)體指針作為方法的接收者。值接收者和指針接收者都可以接收值、指針傳遞的結(jié)構(gòu)體。
nil指針也可以調(diào)用方法。

package main

import (
   "fmt"
)

type TreeNode struct{
   Value int
   Left,Right *TreeNode
}

func createTreeNode(value int) *TreeNode{
   return &TreeNode{Value:value}
}

func (node TreeNode) Print(){
      fmt.Println(node.Value, " ")
}

func (node *TreeNode)traverse(){
   if node != nil{
      //遞歸遍歷左子樹(shù)
      node.Left.traverse()
      node.Print()
      //遞歸遍歷右子樹(shù)
      node.Right.traverse()
   }
}

func (node *TreeNode)setValue(value int){
   if node!= nil{
      node.Value = value
   }else {
      fmt.Println("The node is nil.")
   }
}

func main() {
   var root TreeNode
   root.Value = 0
   root.Left = &TreeNode{Value:1}
   root.Right = &TreeNode{2,nil,nil}
   root.Left.Left = &TreeNode{Value:3}
   root.traverse()

   root.setValue(100)
   root.traverse()
   }

二、包和封裝

1、包簡(jiǎn)介

包用于組織Go源代碼,提供了更好的可重用性與可讀性。由于包提供了代碼的封裝,因此使得Go應(yīng)用程序易于維護(hù)。
Go語(yǔ)言的面向?qū)ο笾恢С址庋b,不支持繼承和多態(tài)。
Go語(yǔ)言使用CamelCase命名方法對(duì)函數(shù)進(jìn)行命名,函數(shù)名稱的首字母大寫(xiě)表示public,小寫(xiě)表示private。
訪問(wèn)權(quán)限是針對(duì)包的,Go語(yǔ)言中每個(gè)目錄是一個(gè)包,包名與目錄名可以不相同。如果目錄下有一個(gè)main函數(shù),目錄只能有一個(gè)main包,main包包含可執(zhí)行入口。
為結(jié)構(gòu)體定義的方法必須在一個(gè)包內(nèi),但可以是不同的文件。

2、包的定義

所有可執(zhí)行的Go程序都必須包含一個(gè)main函數(shù),作為程序運(yùn)行的入口。main函數(shù)應(yīng)該放置于main包中。
包的定義語(yǔ)法如下:
package packagename
指定某一源文件屬于一個(gè)包,應(yīng)該放在每一個(gè)源文件的第一行。
導(dǎo)入一個(gè)已存在的包的語(yǔ)法如下:
import "packagename"?
屬于某一個(gè)包的源文件都應(yīng)該放置于一個(gè)單獨(dú)命名的文件夾里。按照Go語(yǔ)言的慣例,應(yīng)該用包名命名包的文件夾。
在packagename文件夾中,所有文件都會(huì)以package packagename作為開(kāi)頭,因?yàn)槲募A中所有文件Go語(yǔ)言文件都屬于packagename包。

3、包的導(dǎo)入

為了使用自定義包,必須要先導(dǎo)入包。導(dǎo)入自定義包的語(yǔ)法為import path。必須指定自定義包相對(duì)于工作區(qū)內(nèi)?src?文件夾的相對(duì)路徑。
Go語(yǔ)言中導(dǎo)入了包,卻不在代碼中使用包,是非法的。在程序開(kāi)發(fā)階段,常常會(huì)先導(dǎo)入包,而暫不使用,可以使用空白標(biāo)識(shí)符?
var
= packagename.method代碼可以屏蔽錯(cuò)誤。
如果導(dǎo)入一個(gè)包,只為了確保包進(jìn)行了初始化,而無(wú)需使用包中的任何函數(shù)或變量,如需要確保調(diào)用包的init函數(shù),而不需要在代碼中使用包,可以使用空白標(biāo)識(shí)符。
import (_ "packagename")
在使用import導(dǎo)入包的時(shí)候,如果發(fā)生包命名沖突,可以在import的名稱前面加一個(gè)包的別名處理。使用方法如下:
import (packageAnotherName "packagename")

4、init函數(shù)

所有包都可以包含一個(gè)init函數(shù)。init函數(shù)不應(yīng)該有任何返回值類(lèi)型和參數(shù),在用戶代碼中也不能顯式地調(diào)用。init函數(shù)的形式如下:
func init() { }
init函數(shù)可用于執(zhí)行初始化任務(wù),也可用于在開(kāi)始執(zhí)行前驗(yàn)證程序的正確性。
包的初始化順序如下:
A、首先初始化包級(jí)別(Package Level)的變量
B、緊接著調(diào)用init函數(shù)。包可以有多個(gè)init函數(shù)(在一個(gè)文件或分布于多個(gè)文件中),按照編譯器解析的順序進(jìn)行調(diào)用。
C、如果一個(gè)包導(dǎo)入另一個(gè)包,會(huì)最先初始化被導(dǎo)入的包。
D、一個(gè)包可以被導(dǎo)入多次,但只會(huì)被初始化一次。
main包的初始化順序?yàn)椋?br/>A、首先初始化被導(dǎo)入的包。
B、接著初始化包級(jí)別的變量。
C、調(diào)用main包的init函數(shù)。
D、最后調(diào)用main函數(shù)。

三、擴(kuò)展已有類(lèi)型

Go語(yǔ)言中使用定義別名和組合來(lái)擴(kuò)展已有的類(lèi)型。

1、使用組合擴(kuò)展

可以通過(guò)定義一個(gè)新的類(lèi)型,內(nèi)部組合了要擴(kuò)展類(lèi)型的對(duì)象對(duì)已有類(lèi)型進(jìn)行擴(kuò)展。如對(duì)TreeNode類(lèi)型進(jìn)行擴(kuò)展,增加一個(gè)后序遍歷的方法。

//使用組合擴(kuò)展TreeNode類(lèi)型
type BinTreeNode struct{
   node *TreeNode
}
//BinTreeNode的方法
func (binTreeNode *BinTreeNode)postOrderTraverse(){
   if binTreeNode != nil && binTreeNode.node != nil{
      left := BinTreeNode{binTreeNode.node.Right}
      left.postOrderTraverse()
      right := BinTreeNode{binTreeNode.node.Left}
      right.postOrderTraverse()
      node := binTreeNode.node
      node.Print()
   }
}

2、使用別名擴(kuò)展

可以對(duì)已有類(lèi)型定義一個(gè)別名,通過(guò)對(duì)別名類(lèi)型增加新的方法實(shí)現(xiàn)對(duì)已有類(lèi)型的擴(kuò)展。

//定義TreeNode的別名
type PreOrderTreeNode TreeNode

//定義PreOrderTreeNode類(lèi)型的方法
func (pNode *PreOrderTreeNode)preOrderTraverse(){
   if pNode != nil{
      node := (*TreeNode)(pNode)
      node.Print()
      //打印左子樹(shù)
      left := (*PreOrderTreeNode)(pNode.Left)
      left.preOrderTraverse()
      //打印右子樹(shù)
      right := (*PreOrderTreeNode)(pNode.Right)
      right.preOrderTraverse()
   }
}

3、程序?qū)嵗?/h4>
package main

import (
   "fmt"
)

type TreeNode struct{
   Value int
   Left,Right *TreeNode
}

func createTreeNode(value int) *TreeNode{
   return &TreeNode{Value:value}
}

func (node TreeNode) Print(){
      fmt.Println(node.Value, " ")
}

func (node *TreeNode)traverse(){
   if node != nil{
      //遞歸遍歷左子樹(shù)
      node.Left.traverse()
      node.Print()
      //遞歸遍歷右子樹(shù)
      node.Right.traverse()
   }
}

func (node *TreeNode)setValue(value int){
   if node!= nil{
      node.Value = value
   }else {
      fmt.Println("The node is nil.")
   }
}

//使用組合擴(kuò)展TreeNode類(lèi)型
type PostOderTreeNode struct{
   node *TreeNode
}
//BinTreeNode的方法
func (binTreeNode *PostOderTreeNode)postOrderTraverse(){
   if binTreeNode != nil && binTreeNode.node != nil{
      left := PostOderTreeNode{binTreeNode.node.Right}
      left.postOrderTraverse()
      right := PostOderTreeNode{binTreeNode.node.Left}
      right.postOrderTraverse()
      node := binTreeNode.node
      node.Print()
   }
}

//定義TreeNode的別名
type PreOrderTreeNode TreeNode

//定義PreOrderTreeNode類(lèi)型的方法
func (pNode *PreOrderTreeNode)preOrderTraverse(){
   if pNode != nil{
      node := (*TreeNode)(pNode)
      node.Print()
      //打印左子樹(shù)
      left := (*PreOrderTreeNode)(pNode.Left)
      left.preOrderTraverse()
      //打印右子樹(shù)
      right := (*PreOrderTreeNode)(pNode.Right)
      right.preOrderTraverse()
   }
}

func main() {
   var root TreeNode
   root.Value = 0
   root.Left = &TreeNode{Value:1}
   root.Right = &TreeNode{2,nil,nil}
   root.Left.Left = &TreeNode{Value:3}
   root.traverse()

   root.setValue(100)
   root.traverse()
   fmt.Println()
   rootItem1 := PostOderTreeNode{&root}
   rootItem1.postOrderTraverse()
   fmt.Println()
   rootItem2 := (PreOrderTreeNode)(root)
   rootItem2.preOrderTraverse()
}

四、GO環(huán)境變量

1、GOROOT

GOROOT環(huán)境變量是go的安裝路徑。

GOROOT=/usr/local/go
export GOROOT

要執(zhí)行g(shù)o命令和go工具, 需要配置go的可執(zhí)行文件的路徑:
export $PATH:$GOROOT/bin
如果是windows需要使用;符號(hào)分割兩個(gè)路徑, mac和類(lèi)unix使用:符號(hào)分割。

2、GOPATH

go install/go get和 go的工具等會(huì)用到GOPATH環(huán)境變量。
GOPATH是Go語(yǔ)言開(kāi)發(fā)的工作空間,作為編譯后二進(jìn)制的存放目的地和import包時(shí)的搜索路徑。
GOPATH表示代碼包所在的地址,可以設(shè)置多個(gè)。
GOPATH環(huán)境變量默認(rèn)在當(dāng)前用戶主目錄下的go目錄,所有項(xiàng)目和第三方庫(kù)都放在同一個(gè)GOPATH下。
GOPATH用來(lái)存放Go源碼,Go的可運(yùn)行文件,以及相應(yīng)的編譯之后的包文件。所以這個(gè)目錄下面有三個(gè)子目錄:src、bin、pkg
GOPATH允許多個(gè)目錄,當(dāng)有多個(gè)目錄時(shí),請(qǐng)注意分隔符,多個(gè)目錄的時(shí)候Windows是分號(hào),Linux系統(tǒng)是冒號(hào),當(dāng)有多個(gè)GOPATH時(shí),默認(rèn)會(huì)將?go get?的內(nèi)容放在第一個(gè)目錄下。
$GOPATH?目錄約定有三個(gè)子目錄:
A、src目錄存放源代碼(比如:.go .c .h .s等)
B、pkg目錄存放編譯后生成的package(比如:.a)
C、bin目錄存放編譯后生成的可執(zhí)行文件
不能把GOPATH設(shè)置成go的安裝路徑,可以自己在用戶目錄下創(chuàng)建一個(gè)目錄, 如go。

GOPATH=/home/user/go:/home/user/dev
export GOPATH

為了使用方便,通常需要將所有工作空間的bin路徑添加到PATH環(huán)境變量中,如:
export $PATH:$GOPATH/bin
如果$GOPATH有多個(gè)工作目錄,使用?${GOPATH//://bin:}/bin?添加所有的bin目錄。
export $PATH:${GOPATH//://bin:}/bin
GOPATH有兩個(gè)目錄(一個(gè)用于存放第三方包,一個(gè)用戶開(kāi)發(fā)),如果使用?go工具進(jìn)行第三方包的安裝,默認(rèn)會(huì)安裝到第一個(gè)目錄 (/home/user/go),如果在/home/user/dev中寫(xiě)代碼,使用g工具(go install,?go build) 會(huì)將二進(jìn)制包安裝到/home/user/dev中。
GOPATH設(shè)置兩個(gè)目錄的優(yōu)點(diǎn)在于第一個(gè)目錄作為第三方包的存放位置,第二個(gè)目錄作為開(kāi)發(fā)者自己的工作空間。第三方的GOPATH放置到第一位,go 安裝工具會(huì)將其作為默認(rèn)的位置。
當(dāng)使用go命令搜索包時(shí),首先搜索?$GOROOT路徑,然后是$GOPATH/src路徑。

3、遠(yuǎn)程包

go語(yǔ)言有一個(gè)獲取遠(yuǎn)程包的工具就是go get,目前go get支持多數(shù)開(kāi)源社區(qū)(例如:github、googlecode、bitbucket、Launchpad)。
go get github.com/xxx/xxx
go get -u 參數(shù)可以自動(dòng)更新包,而且當(dāng)go get的時(shí)候會(huì)自動(dòng)獲取該包依賴的其它第三方包,默認(rèn)會(huì)安裝到$GOPATH的第一個(gè)目錄。
在代碼中使用遠(yuǎn)程包與使用本地包一樣。
import?"github.com/xxx/xxx"

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。

分享題目:Go語(yǔ)言開(kāi)發(fā)(四)、Go語(yǔ)言面向?qū)ο?創(chuàng)新互聯(lián)
網(wǎng)站URL:http://muchs.cn/article48/ioiep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、電子商務(wù)、網(wǎng)頁(yè)設(shè)計(jì)公司、品牌網(wǎng)站制作虛擬主機(jī)、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷(xiāo)型網(wǎng)站建設(shè)