成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入理解 Go 語言的一等函數及其應用

開發 前端
Go 語言沒有面向對象語言的語法,比如類 、繼承、對象,但 Go 語言中最重要的部分就是支持一等函數。

?1.什么是 Go 中的一等函數

任何一門編程語言都離不開函數,無論是命令式語言 C、多范式編程語言 C++,還是面向對象編程語言 Java、Ruby,動態語言 Python、JavaScript,函數這一語法元素都是當仁不讓的核心。

Go 語言沒有面向對象語言的語法,比如類 、繼承、對象,但 Go 語言中最重要的部分就是支持一等函數。

在 Go 語言中,函數式唯一一種基于特定輸入、實現特定任務并可反饋任務執行結果的代碼塊。本質上 Go 程序就是一組函數的集合。

什么是一等函數

一等函數允許將函數分配給變量(將函數通過變量進行傳遞),作為參數傳遞給其他函數,并從其他函數返回。

2.匿名函數

讓我們從一個簡單的例子開始,它將一個函數分配給一個變量。

package main

import(
"fmt"
)

func main() {
a := func() {
fmt.Println("Learning first class Function")
}
a()

fmt.Printf("%T", a)
}

在上面的程序中,我們利用 a := func()? 給變量 a 分配了一個函數,這是將一個函數賦值給一個變量的語法。

然后我們分配給 a 的函數并沒有名字,這類函數就被稱為匿名函數。

調用這個函數的唯一方法就是使用變量 a?,所以在后面使用 a()? 來調用這個函數,這就會打印出 Learning first class Function;

然后我們打印變量 a? 的類型,這將打印出 func()。

運行結果:

Learning first class Function
func()

也可以調用匿名函數而不把它賦值給一個變量,讓我們來看一下下面的例子是如何做到這一點的:

package main

import (
"fmt"
)

func main() {
func() {
fmt.Println("Learing first class Function")
}()
}

在上面的程序中,在第 8 行定義了一個匿名函數。緊接著我們在第 10 行用 () 調用該函數。這個程序將輸出:

Learing first class Function

也可以像其他函數一樣,向匿名函數傳遞參數:

package main

import (
"fmt"
)

func main() {
func(n string) {
fmt.Println("Welcome to", n)
}("Gophers's World!")
}

我們在上面的代碼中,向匿名函數中傳入一個 n string? 字符串參數,然后在調用時傳入一個 "Gophers's World!" ,此時,運行程序將得到如下的結果:

Welcome to Gophers's World!

3.用戶自定義的函數類型

就像我們自定義結構體類型一樣,在 Go 語言中也支持自定義函數類型:

type add func(a int, b int) int

上面的代碼片段創建了一個新的函數類型 add?,它接受兩個整數參數并返回一個整數,現在我們可以定義 add 類型的變量,如下的代碼:

package main

import (
"fmt"
)

type add func(a int, b int) int

func main() {
var a add = func(a int, b int) int {
return a + b
}

sum := a(2022, 10)
fmt.Println("a + b = ", sum)
}

上面的程序中,我們定義了一個 add? 類型的變量,并給它分配了一個簽名與 add? 類型相符的函數,接著通過 sum := a(2022,10)? 調用并將結果賦給 sum,運行程序后得到如下的結果:

a + b =  2032

4.高階函數

對高階函數的定義是這個函數至少做到以下的某一項的功能:

  • 以一個或者多個函數作為參數
  • 返回一個函數作為其結果

將函數作為參數傳遞給其他函數

package main

import (
"fmt"
)

func simple(a func(a, b int) int) {

fmt.Println(a(60, 7))
}

func main() {

f := func(a, b int) int {
return a + b
}

simple(f)
}

我們定義一個函數 simple? 函數,它接收兩個 int 參數,并返回一個 int 參數,然后把匿名函數傳給變量 f?,然后把 f 作為參數傳遞給 simple? 函數,最終這個程序將打印 67 輸出:

67

從其他函數中返回函數

現在讓我們重寫上面的程序,從 simple 函數中返回一個函數:

package main

import (
"fmt"
)

func simple() func(a, b int) int {

f := func(a, b int) int {
return a + b
}

return f
}

func main() {
s := simple()
fmt.Println(s(2022, 60))
}

運行該程序,得到結果;

2082

5.閉包

閉包是匿名函數的一種特殊情況。閉包是匿名函數,它訪問定義在函數主體之外的變量。

代碼如下:

package main

import (
"fmt"
)

func main() {

a := 2022

func() {
fmt.Println("a = ", a)
}()
}

每個閉包都與它自己周圍的變量綁定。讓我們通過一個簡單的例子來理解這意味著什么。

package main

import (
"fmt"
)

func appendStr() func(string) string {
t := "Hello"
c := func(b string) string {
t = t + " " + b
return t
}
return c
}

func main() {
a := appendStr()
b := appendStr()
fmt.Println(a("World"))
fmt.Println(b("Everyone"))

fmt.Println(a("Gopher"))
fmt.Println(b("!"))
}

在上面的程序中,appendStr? 函數返回一個閉包。這個閉包被綁定到變量 t? 上,變量 a? 和 b? 是閉包,被綁定到它們自己的值 t 上。

我們傳遞參數 World? 給 a?,然后 a? 的值變成了 Hello World。

傳遞參數 Everyone? 給 b,然后 b? 的值變成了 Hello Everyone 。

Hello World  
Hello Everyone
Hello World Gopher
Hello Everyone !

閉包通常也是支持嵌套和 defer 工作的方法。在下面的例子中,我們可以看到一個允許我們嵌套工作的函數閉包:

package main

import (
"fmt"
"sort"
)

func main() {
input := []string{"foo", "bar", "baz"}
var result []string
// closure callback
func() {
result = append(input, "abc")
result = append(result, "def")
sort.Sort(sort.StringSlice(result))
}()
fmt.Println(result)
}

運行結果:

[abc bar baz def foo]

6.一等函數的實際應用

到目前為止,我們已經定義了什么是第一類函數,我們也看到了一些精心設計的例子來學習它們是如何工作的。現在讓我們來寫一個具體的程序,展示第一類函數的實際用途。

我們將創建一個程序,根據一些標準來過濾一部分學生。讓我們一步一步地去做。

首先讓我們定義學生類型:

type student struct {  
firstName string
lastName string
grade string
country string
}

下一步是編寫 filter 函數。這個函數以一個學生切片和一個確定學生是否符合過濾標準的函數為參數。如下:

func filter(s []student, f func(student) bool) []student {  
var r []student
for _, v := range s {
if f(v) == true {
r = append(r, v)
}
}
return r
}

在上述函數中,filter? 的第二個參數是一個函數,它以一個 student 為參數,返回一個 bool 。這個函數確定一個特定的學生是否符合某個標準。我們在第 3 行遍歷學生切片。如果該函數返回真,則意味著該學生通過了過濾標準,并被添加到切片 r 中。

現在來看一個完整的程序:

package main

import (
"fmt"
)

type student struct {
firstName string
lastName string
grade string
country string
}

func filter(s []student, f func(student) bool) []student {
var r []student
for _, v := range s {
if f(v) == true {
r = append(r, v)
}
}
return r
}

func main() {
s1 := student{
firstName: "Naveen",
lastName: "Ramanathan",
grade: "A",
country: "India",
}
s2 := student{
firstName: "Samuel",
lastName: "Johnson",
grade: "B",
country: "USA",
}
s := []student{s1, s2}
f := filter(s, func(s student) bool {
if s.grade == "B" {
return true
}
return false
})
fmt.Println(f)
}

在主函數中,我們首先創建了兩個學生 s1 和 s2,并將他們添加到片斷 s 中。現在我們假設要找出所有成績為 B 的學生,在上述程序中,我們通過傳遞一個檢查學生是否為 B 級的函數,如果是,則返回 true。 上述程序將打印:

[{Samuel Johnson B USA}]

比方說,我們想找到所有來自印度的學生。這可以通過改變過濾器函數的參數來輕松實現。如下:

c := filter(s, func(s student) bool {  
if s.country == "India" {
return true
}
return false
})
fmt.Println(c)

讓我們再寫一個程序來結束本文。這個程序將對一個切片的每個元素進行同樣的操作,并返回結果。

例如,如果我們想將一個切片中的所有整數乘以 5,并返回輸出結果,可以用第一類函數輕松完成。

這類對集合中每個元素進行操作的函數被稱為 map 函數。如下這個程序

package main

import (
"fmt"
)

func iMap(s []int, f func(int) int) []int {
var r []int
for _, v := range s {
r = append(r, f(v))
}
return r
}
func main() {
a := []int{5, 6, 7, 8, 9}
r := iMap(a, func(n int) int {
return n * 5
})
fmt.Println(r)
}

運行結果:

[25 30 35 40 45]

7.總結

在本文中,介紹了什么是一等函數的概念和功能,匿名函數、用戶自定義函數類型、高階函數和閉包,最后給出了一等函數的實際應用例子,希望這篇文章對你有所幫助!

責任編輯:武曉燕 來源: 宇宙之一粟
相關推薦

2021-10-16 17:53:35

Go函數編程

2022-03-27 23:11:39

Go語言函數

2010-07-26 11:27:58

Perl閉包

2023-03-02 08:26:36

RedisAVL紅黑樹

2021-03-18 08:54:55

Go 語言函數

2023-10-27 11:27:14

Go函數

2021-06-30 17:55:34

Redis應用跳表

2023-03-28 07:26:37

2024-04-07 00:04:00

Go語言Map

2024-10-11 11:54:14

C#編寫異步

2024-04-24 08:32:55

.NET對象映射

2021-04-20 23:25:16

執行函數變量

2020-12-16 09:47:01

JavaScript箭頭函數開發

2010-06-28 10:12:01

PHP匿名函數

2019-11-05 10:03:08

callback回調函數javascript

2024-01-01 16:01:22

Python函數

2025-01-13 13:00:00

Go網絡框架nbio

2019-08-19 12:50:00

Go垃圾回收前端

2022-02-14 07:47:26

overlayfsdockerrootfs

2010-06-01 15:25:27

JavaCLASSPATH
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩一区二区三区在线播放 | av福利网 | 国产区在线观看 | 91精品国产91久久综合桃花 | 国产成人精品一区二区三 | 精品一区二区三区免费视频 | 精品国产乱码久久久久久牛牛 | 天堂在线www | 欧美aaa级 | 亚洲成人免费在线观看 | 日韩欧美精品 | 欧美在线一区二区三区 | 国产午夜精品久久久久免费视高清 | 欧美一级视频免费看 | 国产精久久久久久 | 国产成人在线一区 | 成人免费视频在线观看 | 国产精品一区二区久久 | 99久久久久久 | 黄色骚片| 国产精品欧美一区二区三区 | 九九久久精品 | 久久伊人一区 | 午夜小视频在线播放 | 久久久蜜桃一区二区人 | 日韩色图视频 | 亚洲国产一区在线 | 精品视频一区二区三区在线观看 | 国产精品一区在线观看你懂的 | 精品一区免费 | av香蕉 | www..com18午夜观看 | 伊人欧美视频 | 天天影视网天天综合色在线播放 | 国产成人福利视频在线观看 | 欧美中文字幕一区二区 | 国产亚洲欧美另类一区二区三区 | 亚洲成人免费视频在线观看 | 天天干夜夜操 | 91久久久久久久久 | 中文字幕国产第一页 |