国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

golang學習筆記(一)——golang基礎(chǔ)和相關(guān)數(shù)據(jù)結(jié)構(gòu)

lyning / 783人閱讀

摘要:小白前端一枚,最近在研究,記錄自己學習過程中的一些筆記,以及自己的理解。此外,結(jié)構(gòu)體也支持嵌套。在函數(shù)聲明時,在函數(shù)名前放上一個變量,這個變量稱為方法的接收器,一般是結(jié)構(gòu)體類型的。

小白前端一枚,最近在研究golang,記錄自己學習過程中的一些筆記,以及自己的理解。

go中包的依賴管理

go中的切片

byte 和 string

go中的Map

go中的struct結(jié)構(gòu)體

go中的方法

go中的interface接口

interface{}

原文在我的博客中:https://github.com/forthealll...

歡迎star~

1、go中包的依賴管理

首先要了解的是GOPATH的含義,GOPATH是go命令依賴的重要變量,可以通過:

go env

來查看相應(yīng)的開發(fā)環(huán)境中GOPATH的值,也可以通過export GOPATH指定:

export GOPATH = /usr/local/go

指定GOPATH目錄后, GOPATH目錄包含了3個子目錄:

src存放源代碼(比如.go、.h文件等)

pkg編譯時生成的中間文件

bin編譯后生成的可執(zhí)行文件

此外,go的依賴管理中提供了3個主要的命令go build、go get和 go install。

go build: 會編譯目錄下或者指定的.go文件,得到一個可執(zhí)行的文件

go install: 只能在GOPATH目錄下使用,與go build大致相同會編譯目錄下執(zhí)行的.go文件,此外go install還會將可執(zhí)行文件或庫文件安裝到GOPATH目錄下。

go install + 遠程地址: 會將相應(yīng)的代碼下載到GOPATH同時會編譯該遠程包

go get + 遠程地址: 跟go install+遠程地址相同,會下載且編譯

go get u + 遠程地址: 下載并更新相應(yīng)的遠程地址的包,但不會自動編譯

典型的例子,比如下載一個dep包:

go get -u github.com/golang/dep/cmd/dep

上述的go get和go install + 遠程包的方式,不能應(yīng)用于需要版本管理依賴等場景,可以通過安裝dep包,來實現(xiàn)依賴管理。dep提供了幾個常用的命令,分別用于安裝和更新相應(yīng)的go包。

dep init 初始化一個項目依賴

dep ensure 安裝項目所依賴的所有包

dep ensure -update 更新項目中的所有包

dep ensure -add github.com/pkg/errors 為項目添加單個依賴包

此外通過Gopkg.toml里面可以指定所依賴包的git分支,版本號等等,且在dep ensure -add中也可以指定分支和版本號,比如:

dep ensure -add github.com/pkg/foo@^1.0.1

提到包(package),必須補充一句,在go中如果在其他包中引用變量,是通過:

包名.變量名

的形式,在這里變量名必須是大寫的,也就是說在go的包中,變量能否導(dǎo)出是根據(jù)變量的大小寫來確定的,普遍認為如果變量是大寫的就是在包內(nèi)導(dǎo)出的,如果是變量小寫的就是默認是包的私有變量。

2、go中的切片

在go的函數(shù)調(diào)用中,如果傳遞的參數(shù)是一個較大的數(shù)組,顯然如果直接將數(shù)組作為實參傳入,在執(zhí)行函數(shù)的過程中,實際上會拷貝一份該數(shù)組,會造成內(nèi)存的浪費等。標準的做法,是傳入數(shù)組的指針,或者對于數(shù)組的部分引用。

這里關(guān)于數(shù)組的部分引用,就是slice切片

(1)、go中的切片簡介

數(shù)組和切片之間存在著緊密的聯(lián)系,slice提供了訪問數(shù)組子序列的功能。所謂的切片是對于數(shù)組的部分引用,slice由三部分組成指針、長度和容量。

指針: 指向第一個slice元素所對應(yīng)的數(shù)組元素的地址

長度: slice中元素的數(shù)目

容量: slice中最多可容納元素的數(shù)目

切片的定義方式:

var slice1 []type = make([]type, len, cap)

分別指定切片的類型,長度以及容量。

切片的初始化:

s := [] int { 1,2,3 }

或者通過已經(jīng)存在的數(shù)組來實現(xiàn)切片的初始化,

arr = [10]int {1,2,3,4,5,6,7,8,9,10}
s:=arr[1:5] // arr[startIndex:endIndex]
(2)、go中的切片注意點

go中的slice切片有一個注意點,就是如何判斷切片為空,邊界情況大致如下所示:

var s []int   //len(s)==0,s==nil
s = nil       //len(s)==0,s==nil
s = []int(nil)//len(s)==0,s==nil
s = []int{}   //len(s)==0,s!=nil

顯然如果通過s==nil來判斷,不能區(qū)別第四種場景,因此判斷切片為空的正確方式是len(s)==0.

3、byte 和 string

下述的方法將返回一個byte的切片:

var test:= []byte("hello")

go遍歷slice動態(tài)刪除 map遍歷刪除安全.

4、go中的Map

map是一個無序的key/value對的集合,其中在每一個map中key是唯一的。go中的map只要坑在于map是無序的。

(1)、Map簡介

聲明一個map:

var ages map[string]int  //同樣初始的情況下,ages = nil
ages == nil // true

如果聲明了但是沒有賦值,那么嘗試插入一對key/value會報錯,比如上述聲明但沒有初始化的情況下:

age["jony"] = 25 // 會panic

解決方法,就是給age定義后賦值:

ages = make(map[string]int)

或者定義的時候同時賦值:

ages := map[string]int{

}

此后插入不存在的key/value就不會報錯。

注意:嘗試從map中去一個不存在的key,默認的value值為0

(2)、Map無序性

我們從map的遍歷結(jié)果,來說明map是無序的。比如我們以這么一個map為例:

var ages = map[string]int{
"a":21,
"b":22,
"c":23,
};
for name,age := range ages {
  fmt.Printf("%s	%d
",name,age);
}

通過for range可以遍歷map對象,分別執(zhí)行三次遍歷后,來看遍歷的結(jié)果

第一次輸出:

c 23
a 21
b 22

第二次輸出:
c 23
b 22
a 21

第三次輸出:
a 21
b 22
c 23

從上述的結(jié)果我們也可以看出map的每次遍歷的結(jié)果都是不確定的。

注意:Map的value類型不僅僅可以是基本類型,也可以是聚合類型,比如map或者slice。

5 、go中的struct結(jié)構(gòu)體

跟C++中的結(jié)構(gòu)體類似,go中的結(jié)構(gòu)體是一種聚合數(shù)據(jù)類型,由0個或者多個任意值聚合成實體。

(1)、結(jié)構(gòu)體簡介

聲明一個結(jié)構(gòu)體很簡單,比如我們聲明了一個Person結(jié)構(gòu)體:

type Person struct {
   name string
   age int
   salary int
}

然后可以聲明一個Person類型的變量:

var person Person

然后可以通過點操作符訪問和賦值。

person.age = 25

此外,可以通過取地址符號加點操作符來訪問和賦值,下述取地址的方式效果與上述是相同的。

(&person).age = 25

此外,結(jié)構(gòu)體也支持嵌套。

6、go中的方法

在go中沒有明確的定義類,但是可以將結(jié)構(gòu)體struct來類比其他語言中的class。

go中的方法與結(jié)構(gòu)體相關(guān),為了說名go中的方法,我們先從go中的函數(shù)講起。

(1)、go中的函數(shù)簡介

在go中函數(shù)聲明包括函數(shù)名、形參列表、返回值列表(可省略 不傲視無返回值)以及函數(shù)體。

func name (parameter-list)(result-list){


}

比如我們有一個count函數(shù)可以如此簡單的定義:

func count(x,y int) int {
   return x + y
}
(2)、go中方法簡介

在函數(shù)定義的基礎(chǔ)上我們來介紹一下,如何定義方法。在函數(shù)聲明時,在函數(shù)名前放上一個變量,這個變量稱為方法的接收器,一般是結(jié)構(gòu)體類型的。

當然也不一定是結(jié)構(gòu)體,基本類型數(shù)值、字符串、slice和map上面都可以作為接收器來定義方法。

聲明方法的方式具體可以如下所示:

func (receive Receive) name(parameter-list)(result-list){


}

從上述的聲明中也可以看出來只不過在函數(shù)的技術(shù)上增加了第一個參數(shù)接收器,為相應(yīng)的接收器增加了該名稱的方法。比如我們定一個Person結(jié)構(gòu)體,并為其聲明sellHello方法:

type Person struct {
   name string
   age int
   salary int
}

func (person Person) sayHello() string{
  return "Hello "+ person.name
}

p := Person{
   name: "Jony",
   age: 25,
   salary:100
}

fmt.Println(p.sayHello());//輸出Hello Jony

上述就是在結(jié)構(gòu)體Person上定義了一個sayHello方法,在結(jié)構(gòu)體被初始化后,可以通過p.sayHello()的方式直接調(diào)用。

除此之外,我們前面將到定義方法時的接收器不一定是一個結(jié)構(gòu)體,接收器也可以接受基本類型等,比如:

type Mystring string;

func (mystring Mystring)sayHello() string{
  return "Hello"+ string(mystring);
}

var m Mystring
m = "Jony"
fmt.Println(m.sayHello());

上述的例子同樣會輸出Hello Jony.

甚至nil也可以作為方法的接收器,這里就不具體舉例。

(3)、基于指針對象的方法

在函數(shù)調(diào)用時,是對實參的一個拷貝,如果函數(shù)需要更新一個變量,或者傳遞的參數(shù)過大,默認拷貝太為負責,我們經(jīng)常會使用指針的形式,對于方法而言也同樣如此,也就是說方法的接收器可以是指針類型。

對比于上述非指針類型的方法,聲明指針類型的方法具體如下所示:

func (receive *Receive) name(parameter-list)(result-list){


}

指針類型的參數(shù)作為接收器,可以修改傳入?yún)?shù)的實際變量的值。

type Person struct {
  name string
  age int
  salary int
}
func (person *Person) changeAge(newAge int){
  (*person).age = newAge
}
p.changeAge(30);
fmt.Println(p.age); //輸出了30,發(fā)現(xiàn)age確實發(fā)生了改變。

7、go中的interface接口

我們前面也說過go不是一種傳統(tǒng)的面向?qū)ο蟮恼Z言,沒有類和繼承的概念,go里面通過interface接口可以實現(xiàn)很多面向?qū)ο蟮奶匦浴?/p>

接口的通俗定義:

接口提供了一種方式來說明對象的行為,接口定義了一組方法,但是不包含實現(xiàn)。

(1)、interface接口簡介

可以通過如下格式來定義接口:

type Namer interface {
   Method1(param_list) return_type
   Method2(param_list) return_type
   ...
}

go中的接口都很簡短,一般包含了0-3個方法。

同時我們可以通過:

var ai Namer 

來定義一個接口類型的變量,初始值為nil.接口類型的變量是一個指針,聲明而未賦值的情況下就為nil。

go中的接口有以下需要注意的點:

一個類型可以實現(xiàn)多個接口

接口類型可以包含一個實例的引用,該實例的類型實現(xiàn)了此接口

即使接口在類型之后定義,二者存在不同的包中,被多帶帶編譯,但是只要類型實現(xiàn)了接口中的方法,它就實現(xiàn)了此接口

實現(xiàn)某個接口的類型,除了實現(xiàn)接口方法外,還可以有其他的方法

上述幾點都比較好理解,具體第二點,舉例來說:

type Person struct {
 name string
 age int
 salary int
}
type Say interface {
  sayHello() string
}
func (person Person) sayHello() string {
  return "Hello "+person.name
}

func main() {
  p := new(Person)
  p.name = "Jony"

  var s Say;
  s = p;
  fmt.Println(s)
}

上述例子中,我們首先new了一個Person結(jié)構(gòu)體類型的變量,并賦值給p,因為Person接口體中實現(xiàn)了Say接口中的所有方法sayHello等。因此我們就說Person實現(xiàn)了Say接口,因此Person的實例p,可以賦值給一個Say接口類型的變量s。

此時的s是個指針,指向Person結(jié)構(gòu)體實例p。

(2)、interface接口類型斷言

任何類型只要實現(xiàn)了接口中的所有方法,我們就說該類型實現(xiàn)了該接口。這樣一個接口類型的變量varI可以包含任何類型的值,在go中提供了一種安全的方式來檢測它的動態(tài)類型。

if v,ok := varI.(T);ok {
   Process(v)
   return
}

如果轉(zhuǎn)化合法,那么v是varI轉(zhuǎn)化到類型T的值,ok會是true,否則v是類型T的零值,ok是false。這是一種安全的轉(zhuǎn)化方式不會有錯誤發(fā)生。

我們還是接著上面的代碼來講我們的例子:

type Person struct {
 name string
 age int
 salary int
}

type Say interface {
  sayHello() string
}

func (person Person) sayHello() string {
  return "Hello "+person.name
}

func main() {
  p := new(Person)
  p.name = "Jony"

  var s Say;
  s = p;
  if t,ok := s.(*Person);ok {
    fmt.Printf("The type of s is:%T
",t);
  }
}

輸出的結(jié)果為The type of s is:*main.Person。也可以使用特殊的type-switch來判斷。

switch t:= s.(*Person){
   case *Person:
      fmt.Printf("The type of s is:%T
",t);
   case nil:
      ...
   default:
      ...
}
8、interface{}

interface{}是一個空接口,任何類型的值都可以復(fù)制給interface{}類型的變量。

比如,我們首先聲明一個類型為interface{}的變量:

var test interface{}

任意類型的值都可以復(fù)制給test,比如下列基本類型的值復(fù)制給test是有效的:

var test interface{}
test = 1
test = true
test ="Hello"

此外,復(fù)雜的派生類型也可以賦值給test,我們以指針類型舉例:

var test interface{}
var a = 1
test = &a 

interface類型的變量是沒有類型的,但是我們可以人為的進行類型轉(zhuǎn)換:

var test interface{}
var a string
test = "hello"
a = test.(string)

上述,可以將test轉(zhuǎn)化成string類型,這樣就可以賦值給string類型變量a了。通過.(類型名)的方法可以將interface{}類型的變量轉(zhuǎn)化成任意的類型。

最后舉一個簡單的例子:

func main() {
   a := make([]interface{},10)
   b :=1
   a[1]=&b
   fmt.Println(*(a[1].(*int)))
}

上述代碼發(fā)現(xiàn),將interface{}類型切片中的某一元素的值復(fù)制給了int指針類型,然后進行了類型轉(zhuǎn)化,將interface{}類型的變量轉(zhuǎn)換成了int指針類型。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108853.html

相關(guān)文章

  • golang 入門

    摘要:而且數(shù)組是定長的,而切片可以調(diào)整長度。也就是說類型的值可以用于表示任意語言類型的值。下劃線讓編譯器接受這類導(dǎo)入,并且調(diào)用對應(yīng)包內(nèi)的所有代碼文件里定義的函數(shù)。結(jié)構(gòu)體可以當做是一種數(shù)據(jù)類型一般都默認函 緣起 之前下載視頻用的you-get,但是b站一直下不了,優(yōu)酷也經(jīng)常出問題,所以接觸到lulu https://github.com/iawia002/Lulu 這個也是基于you-get ...

    loonggg 評論0 收藏0
  • golang自定義路由控制實現(xiàn)(

    摘要:中的設(shè)計非常輕量,又兼具很高的擴展性,初學者都可以輕易的設(shè)計出自定義的路由功能,使用上十分簡單這里來吐槽一下的,雖然我也對愛得深沉,下面請看的。一般網(wǎng)站的路由規(guī)則太多了,編寫繁瑣,可以通過的方法進行一種簡化。????由于本人之前一直是Java Coder,在Java web開發(fā)中其實大家都很依賴框架,所以當在學習Golang的時候,自己便想著在Go開發(fā)中脫離框架,自己動手造框架來練習。通過學...

    番茄西紅柿 評論0 收藏0
  • golang自定義路由控制實現(xiàn)(

    摘要:中的設(shè)計非常輕量,又兼具很高的擴展性,初學者都可以輕易的設(shè)計出自定義的路由功能,使用上十分簡單這里來吐槽一下的,雖然我也對愛得深沉,下面請看的。一般網(wǎng)站的路由規(guī)則太多了,編寫繁瑣,可以通過的方法進行一種簡化。????由于本人之前一直是Java Coder,在Java web開發(fā)中其實大家都很依賴框架,所以當在學習Golang的時候,自己便想著在Go開發(fā)中脫離框架,自己動手造框架來練習。通過學...

    darkerXi 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<