亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口

 更新時(shí)間:2022年05月23日 17:07:15   作者:Arway  
這篇文章主要介紹了Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口,文章圍繞主題的相關(guān)資料展開詳細(xì)的文章說明,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

1. 函數(shù)

Go語言的函數(shù)屬于“一等公民”(first-class),也就是說:

  • 函數(shù)本身可以作為值進(jìn)行傳遞。
  • 支持匿名函數(shù)和閉包(closure)。
  • 函數(shù)可以滿足接口。

1.1 函數(shù)返回值

同一種類型返回值

func typedTwoValues() (int, int) {
    return 1, 2
}
a, b := typedTwoValues()
fmt.Println(a, b)

帶變量名的返回值

func named Ret Values() (a, b int) {
       a = 1
       b = 2
       return
}

函數(shù)使用命名返回值時(shí),可以在return中不填寫返回值列表,如果填寫也是可行的

函數(shù)中的參數(shù)傳遞

Go語言中傳入和返回參數(shù)在調(diào)用和返回時(shí)都使用 值傳遞 ,這里需要注意的是 指針、切片和map等引用型對象指向的內(nèi)容在參數(shù)傳遞中不會發(fā)生復(fù)制,而是將指針進(jìn)行復(fù)制,類似于創(chuàng)建一次引用。

函數(shù)變量

在Go語言中,函數(shù)也是一種類型,可以和其他類型一樣被保存在變量中

func fire() {
	fmt.Println("fire")
}
func main() {
	var f func()  //將變量f聲明為func()類型,此時(shí)f就被俗稱為“回調(diào)函數(shù)”。此時(shí)f的值為nil。
	f = fire
	f()
}

1.2 匿名函數(shù)——沒有函數(shù)名字的函數(shù)

Go語言支持匿名函數(shù),即在需要使用函數(shù)時(shí),再定義函數(shù),匿名函數(shù)沒有函數(shù)名, 只有函數(shù)體 ,函數(shù)可以被作為一種類型被賦值給函數(shù)類型的變量, 匿名函數(shù)也往往以變量方式被傳遞 。

在定義時(shí)調(diào)用匿名函數(shù)

匿名函數(shù)可以在聲明后調(diào)用,例如:

func(data int) {
     fmt.Println("hello", data)
}(100)

將匿名函數(shù)賦值給變量

匿名函數(shù)體可以被賦值,例如:

// 將匿名函數(shù)體保存到f()中
f := func(data int) {
       fmt.Println("hello", data)
}
// 使用f()調(diào)用
f(100)

匿名函數(shù)用作回調(diào)函數(shù)

使用時(shí)再定義匿名函數(shù),不使用先在被調(diào)用函數(shù)里面進(jìn)行聲明,這就是回調(diào)精髓

// 遍歷切片的每個(gè)元素,通過給定函數(shù)進(jìn)行元素訪問?
   func visit(list []int, f func(int)) {
        for _, v := range list {
              f(v)
        }
   }
   func main() {

       // 使用匿名函數(shù)打印切片內(nèi)容
        visit([]int{1, 2, 3, 4}, func(v int) {
              fmt.Println(v)
        })
   }

可變參數(shù)——參數(shù)數(shù)量不固定的函數(shù)形式

所有參數(shù)都是可變參數(shù):fmt.Println

func Println(a ...interface{}) (n int, err error) {
    return Fprintln(os.Stdout, a...)
}

fmt.Println在使用時(shí),傳入的值類型不受限制,例如:

fmt.Println(5, "hello", &struct{ a int }{1}, true)

當(dāng)可變參數(shù)為 interface{} 類型時(shí),可以傳入任何類型的值

部分參數(shù) 是可變參數(shù):fmt.Printf

fmt.Printf的第一個(gè)參數(shù)為參數(shù)列表,后面的參數(shù)是可變參數(shù):

func Printf(format string, a ...interface{}) (n int, err error) {
	return Fprintf(os.Stdout, format, a...)
}
------------------------------------------------------
fmt.Printf("pure string\n")
fmt.Printf("value: %v %f\n", true, math.Pi)

1.3 閉包

閉包可以理解成定義在函數(shù)內(nèi)部的一個(gè)函數(shù)。本質(zhì)上,閉包是函數(shù)內(nèi)部和函數(shù)外部連接起來的橋梁。簡單來說,閉包=函數(shù)+引用環(huán)境

func main() {
	var f = add()
	fmt.Printf("f(10): %v\n", f(10))
	fmt.Printf("f(20): %v\n", f(20))
	// f(10): 10
	// f(20): 30
}
func add() func(int) int {
	var x int
	return func(y int) int {
		x += y
		return x
	}
}

1.4 defer語句

defer語句將其后面跟隨的語句進(jìn)行延遲處理,被defer的語句按先進(jìn)后出的方式執(zhí)行(最先defer的語句最后執(zhí)行,后被defer的語句先執(zhí)行)。

特性:

  • 關(guān)鍵字defer用于注冊延遲調(diào)用
  • 直到調(diào)用return之前才執(zhí)行(故可用來作資源清理)
  • 多個(gè)defer語句,F(xiàn)ILO方式執(zhí)行
  • defer中的變量,在defer聲明時(shí)就定義了

用途:

  • 關(guān)閉文件句柄
  • 鎖資源釋放
  • 數(shù)據(jù)庫連接釋放

處理運(yùn)行時(shí)發(fā)生的錯(cuò)誤

Go語言的錯(cuò)誤處理思想及設(shè)計(jì)包含以下特征:

  •  一個(gè)可能造成錯(cuò)誤的函數(shù),需要返回值中返回一個(gè) 錯(cuò)誤接口(error )。如果調(diào)用是成功的,錯(cuò)誤接口將返回nil,否則返回錯(cuò)誤。
  • 在函數(shù)調(diào)用后需要檢查錯(cuò)誤,如果發(fā)生錯(cuò)誤,進(jìn)行必要的錯(cuò)誤處理。

錯(cuò)誤接口的定義格式

error是Go系統(tǒng)聲明的接口類型,代碼如下:

type error interface {
    Error() string    // 返回錯(cuò)誤的具體描述.
}

所有符合Error() string格式的接口都能實(shí)現(xiàn)錯(cuò)誤接口。

定義一個(gè)錯(cuò)誤

在Go語言中,使用errors包進(jìn)行錯(cuò)誤的定義,格式如下:

var err = errors.New("this is an error")

錯(cuò)誤字符串由于相對固定,一般在包作用域聲明, 應(yīng)盡量減少在使用時(shí)直接使用errors.New返回。

宕機(jī)(panic)——程序終止運(yùn)行

手動(dòng)觸發(fā)宕機(jī)

Go語言可以在程序中手動(dòng)觸發(fā)宕機(jī),讓程序崩潰,這樣開發(fā)者可以及時(shí)地發(fā)現(xiàn)錯(cuò)誤,同時(shí)減少可能的損失。

Go語言程序在宕機(jī)時(shí),會將堆棧和goroutine信息輸出到控制臺,所以宕機(jī)也可以方便地知曉發(fā)生錯(cuò)誤的位置。

package main
func main() {
panic("crash")
}

panic()的參數(shù)可以是任意類型,

當(dāng)panic()觸發(fā)的宕機(jī)發(fā)生時(shí),panic()后面的代碼將不會被運(yùn)行,但是在panic()函數(shù)前面已經(jīng)運(yùn)行過的defer語句依然會在宕機(jī)發(fā)生時(shí)發(fā)生作用,

1.5 宕機(jī)恢復(fù)(recover)——防止程序崩潰

無論是代碼運(yùn)行錯(cuò)誤由Runtime層拋出的panic崩潰,還是主動(dòng)觸發(fā)的panic崩潰,都可以配合defer和recover實(shí)現(xiàn)錯(cuò)誤捕捉和恢復(fù),讓代碼在發(fā)生崩潰后允許繼續(xù)運(yùn)行。

Go沒有異常系統(tǒng),其使用panic觸發(fā)宕機(jī)類似于其他語言的拋出異常,那么recover的宕機(jī)恢復(fù)機(jī)制就對應(yīng)try/catch機(jī)制。

panic和recover的關(guān)系:

  • 有panic沒recover,程序宕機(jī)。
  • 有panic也有recover捕獲,程序不會宕機(jī)。執(zhí)行完對應(yīng)的defer后,從宕機(jī)點(diǎn)退出當(dāng)前函數(shù)后繼續(xù)執(zhí)行。

提示:雖然panic/recover能模擬其他語言的異常機(jī)制,但并不建議代表編寫普通函數(shù)也經(jīng)常性使用這種特性。

2. 結(jié)構(gòu)體

結(jié)構(gòu)體成員是由一系列的成員變量構(gòu)成,這些成員變量也被稱為“字段”。

字段有以下特性:

  • 字段擁有自己的類型和值。
  • 字段名必須唯一。
  • 字段的類型也可以是結(jié)構(gòu)體,甚至是字段所在結(jié)構(gòu)體的類型。

Go語言中沒有“類”的概念,也不支持“類”的繼承等面向?qū)ο蟮母拍睢?/p>

Go語言的結(jié)構(gòu)體與“類”都是復(fù)合結(jié)構(gòu)體,但Go語言中結(jié)構(gòu)體的內(nèi)嵌配合接口比面向?qū)ο缶哂懈叩臄U(kuò)展性和靈活性。

Go語言不僅認(rèn)為結(jié)構(gòu)體能擁有方法,且每種自定義類型也可以擁有自己的方法。

2.1 定義與給結(jié)構(gòu)體賦值

基本形式:

type Point struct {
	X int
	Y int
}
var p Point
p.X = 10
p.Y = 20

結(jié)構(gòu)體的定義只是一種內(nèi)存布局的描述,只有當(dāng)結(jié)構(gòu)體實(shí)例化時(shí),才會真正地分配內(nèi)存

創(chuàng)建指針類型的結(jié)構(gòu)體:

type Player struct {
	name string
	age int
}
p = new(Player)
p.name = "james"
p.age = 40

取結(jié)構(gòu)體的地址實(shí)例化:

//使用結(jié)構(gòu)體定義一個(gè)命令行指令(Command),指令中包含名稱、變量關(guān)聯(lián)和注釋等
type Command struct {
	name string
	Var *int
	comment string
}
var version int = 1
cmd := &Command{}
cmd.name = "version"
cmd.Var = &version
cmd.comment = "show version"

使用鍵值對填充結(jié)構(gòu)體:

type People struct {
	name string
	child *People
}
relation := &People{
	name: "爺爺"
	child: &People{
		name: "爸爸"
		child: &People{
			name: "我"
		},
	}
}

3. 方法

Go語言中的方法(Method)是一種作用于特定類型變量的函數(shù)。這種特定類型變量叫做接收器( Receiver )。

如果將特定類型理解為結(jié)構(gòu)體或“類”時(shí),接收器的概念就類似于其他語言中的 this 或者 self 。

3.1 結(jié)構(gòu)體方法

創(chuàng)建一個(gè)背包 Bag 結(jié)構(gòu)體為其定義把物品放入背包的方法 insert :

type Bag struct {
	items[] int
}
func (b *Bag) insert(itemid int) {
	b.items = append(b.items, itemid)
} 
func main() {
	b := new(Bag)
	b.insert(1001)
}

(b*Bag) 表示接收器,即 Insert 作用的對象實(shí)例。每個(gè)方法只能有一個(gè)接收器。

3.2 接收器

接收器是方法作用的目標(biāo)

接收器根據(jù)接收器的類型可分:

  • 指針接收器
  • 非指針接收器
  • 兩種接收器在使用時(shí)會產(chǎn)生不同的效果。根據(jù)效果的不同,兩種接收器會被用于不同性能和功能要求的代碼中。

指針接收器

由于指針的特性,調(diào)用方法時(shí),修改接收器指針的任意成員變量,在方法結(jié)束后,修改都是有效的。

// 定義屬性結(jié)構(gòu)
type Property struct {
	value int
}
// 設(shè)置屬性值方法
func (p *Property) setVal(val int) {
	p.value = val
}
// 獲取屬性值方法
func (p *Property) getVal() int {
	return p.value
}
func main() {
	p := new(Property)
	p.value = 123
	fmt.Println(p.getVal())
	p.setVal(666)
	fmt.Println(p.getVal())
}

非指針類型接收器

當(dāng)方法作用于非指針接收器時(shí),Go語言會在代碼運(yùn)行時(shí) 將接收器的值復(fù)制一份 。在非指針接收器的方法中可以獲取接收器的成員值, 但修改后無效 。

type Point struct {
	x, y int
}
func (p Point) add(other Point) Point {
	return Point{p.x + other.x, p.y + other.y}
}
func main() {
	// 初始化點(diǎn)
	p1 := Point{1, 1}
	p2 := Point{2, 2}
	res := p1.add(p2)
	fmt.Println(res)

	p3 := Point{3, 3}
	p4 := p1.add(p2).add(p3)
	fmt.Println(p4)
}

指針接收器和非指針接收器的使用:

指針和非指針接收器的使用在計(jì)算機(jī)中, 小對象 由于值復(fù)制時(shí)的速度較快,所以適合使用非指針接收器。 大對象 因?yàn)閺?fù)制性能較低,適合使用指針接收器,在接收器和參數(shù)間傳遞時(shí)不進(jìn)行復(fù)制,只是傳遞指針。

4. 接口

接口是雙方約定的一種合作協(xié)議。接口實(shí)現(xiàn)者不需要關(guān)心接口會被怎樣使用,調(diào)用者也不需要關(guān)心接口的實(shí)現(xiàn)細(xì)節(jié)。 接口是一種類型,也是一種抽象結(jié)構(gòu),不會暴露所含數(shù)據(jù)的格式、類型及結(jié)構(gòu)。

4.1 聲明接口

type 接口類型名 interface {
	方法1(參數(shù)列表) 返回值
	...
}

Go語言的接口在命名時(shí),一般會在單詞后面添加er,如有寫操作的接口叫Writer,有字符串功能的接口叫Stringer,有關(guān)閉功能的接口叫Closer等

方法名:當(dāng)方法名首字母是大寫時(shí),且這個(gè)接口類型名首字母也是大寫時(shí),這個(gè)方法可以被接口所在的包(package)之外的代碼訪問。

io包中提供的Writer接口:

type Writer interface {
	Write(p []type) (n int, err error)
}

4.2 實(shí)現(xiàn)接口

實(shí)現(xiàn)接口的條件:

  • 接口的方法與實(shí)現(xiàn)接口的類型方法格式一致
  • 接口中所有方法均被實(shí)現(xiàn)

例:為了抽象數(shù)據(jù)寫入的過程,定義Data Writer接口來描述數(shù)據(jù)寫入需要實(shí)現(xiàn)的方法。

// 定義一個(gè)數(shù)據(jù)寫入器接口
type DataWriter interface {
	WriteData(data interface{}) error
}
// 定義文件結(jié)構(gòu),用于實(shí)現(xiàn)DataWriter
type file struct {
}
// 實(shí)現(xiàn)DataWriter接口的方法
func (d *file) WriteData(data interface{}) error {
	// 模擬寫入數(shù)據(jù)
	fmt.Println("Write Data:", data)
	return nil
}
func main() {
	// 實(shí)例化file
	f := new(file)
	// 聲明一個(gè)DataWriter接口
	var writer DataWriter
	// 將接口賦值,也就是*file
	writer = f
	writer.WriteData("one line data")
}

Go語言的接口實(shí)現(xiàn)是隱式的,無須讓實(shí)現(xiàn)接口的類型寫出實(shí)現(xiàn)了哪些接口。這個(gè)設(shè)計(jì)被稱為非侵入式設(shè)計(jì)。

到此這篇關(guān)于Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口的文章就介紹到這了,更多相關(guān)Go 函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go?字符串修改的操作代碼

    go?字符串修改的操作代碼

    這篇文章主要介紹了go?字符串修改,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Golang中interface的基本用法詳解

    Golang中interface的基本用法詳解

    Go 中接口也是一個(gè)使用得非常頻繁的特性,好的軟件設(shè)計(jì)往往離不開接口的使用,比如依賴倒置原則(通過抽象出接口,分離了具體實(shí)現(xiàn)與實(shí)際使用的耦合)。 今天,就讓我們來了解一下 Go 中接口的一些基本用法
    2023-01-01
  • golang?開啟opencv圖形化編程

    golang?開啟opencv圖形化編程

    這篇文章主要為大家介紹了golang?開啟opencv圖形化編程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 優(yōu)雅管理Go?Project生命周期

    優(yōu)雅管理Go?Project生命周期

    這篇文章主要為大家介紹了如何優(yōu)雅的管理Go?Project生命周期,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Golang函數(shù)這些神操作你知道哪些

    Golang函數(shù)這些神操作你知道哪些

    這篇文章主要為大家介紹了一些Golang中函數(shù)的神操作,不知道你都知道哪些呢?文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下
    2023-02-02
  • golang實(shí)現(xiàn)圖像驗(yàn)證碼的示例代碼

    golang實(shí)現(xiàn)圖像驗(yàn)證碼的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用golang實(shí)現(xiàn)簡單的圖像驗(yàn)證碼,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • go語言實(shí)現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析

    go語言實(shí)現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析

    這篇文章主要介紹了go語言實(shí)現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程

    go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程

    這篇文章主要為大家介紹了go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動(dòng)流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • go內(nèi)置函數(shù)copy()的具體使用

    go內(nèi)置函數(shù)copy()的具體使用

    當(dāng)我們在Go語言中需要將一個(gè)切片的內(nèi)容復(fù)制到另一個(gè)切片時(shí),可以使用內(nèi)置的copy()函數(shù),本文就介紹了go內(nèi)置函數(shù)copy()的具體使用,感興趣的可以了解一下
    2023-08-08
  • Go?處理大數(shù)組使用?for?range?和?for?循環(huán)的區(qū)別

    Go?處理大數(shù)組使用?for?range?和?for?循環(huán)的區(qū)別

    這篇文章主要介紹了Go處理大數(shù)組使用for?range和for循環(huán)的區(qū)別,對于遍歷大數(shù)組而言,for循環(huán)能比for?range循環(huán)更高效與穩(wěn)定,這一點(diǎn)在數(shù)組元素為結(jié)構(gòu)體類型更加明顯,下文具體分析感興趣得小伙伴可以參考一下
    2022-05-05

最新評論