[每周一更]-(第52期):Go的函数式编程

参考地址

函数式编程(Functional Programming / FP)作为一种编程范式,具有无状态、无副作用、并发友好、抽象程度高等优点。

Go语言并不是一门纯粹的函数式编程语言,但它支持一些函数式编程的特性和思想。函数式编程是一种编程范式,

其核心理念是将计算视为函数应用的组合,强调使用纯函数、不可变性和避免副作用。

声明式编程:函数式编程倾向于使用声明式风格,将关注点放在"做什么"而不是"如何做"上。通过使用函数组合、管道操作符等,可以在Go中实现声明式的风格,使代码更易读、简洁和可维护。

  • 高阶函数:Go语言中函数是一等公民,可以作为参数传递给其他函数,也可以作为返回值。这使得我们可以编写高阶函数,即接受其他函数作为参数或返回函数的函数。
  • 闭包:Go语言支持闭包,可以在函数内部定义函数,并访问外部函数的变量。闭包在函数式编程中常用于创建不可变的函数,或者捕获一些状态并将其封装在函数中。
  • 函数组合:通过将多个函数组合在一起形成新的函数,可以实现函数的复用和组合。可以使用函数的嵌套调用、函数参数传递和返回函数等方式来实现函数组合。
  • 纯函数:纯函数是指没有副作用的函数,即函数的返回值仅由输入决定,不依赖于外部状态。在Go中,可以通过避免修改函数外部的变量和数据,以及避免使用全局状态,来编写纯函数。
  • 不可变性:尽量避免在函数中修改传入的参数或外部变量,而是创建新的数据结构或使用函数返回新的结果。这样可以减少副作用,增加代码的可读性和可维护性。
  • 函数链式调用:通过返回对象本身或其他具有相同方法的对象,可以实现函数链式调用的风格。这在Go中常用于构建流畅的API接口或操作符。

高阶函数示例:

定义一个高阶函数mapInts,它接受一个整数切片和一个函数作为参数,并将该函数应用于切片中的每个元素。

func mapInts(nums []int, f func(int) int) []int {
    result := make([]int, len(nums))
    for i, num := range nums {
        result[i] = f(num)
    }
    return result
}

func main() {
    nums := []int{1, 2, 3, 4, 5}
    doubled := mapInts(nums, func(x int) int {
        return x * 2
    })
    fmt.Println(doubled) // Output: [2 4 6 8 10]
}

闭包示例:

使用闭包创建一个计数器函数,每次调用计数器函数都会增加计数器的值。

func newCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    counter := newCounter()
    fmt.Println(counter()) // Output: 1
    fmt.Println(counter()) // Output: 2
    fmt.Println(counter()) // Output: 3
}

函数组合示例:

定义两个函数addOne和double,然后将它们组合在一起形成一个新的函数addOneAndDouble。

func addOne(x int) int {
    return x + 1
}

func double(x int) int {
    return x * 2
}

func compose(f func(int) int, g func(int) int) func(int) int {
    return func(x int) int {
    return f(g(x))
    }
}

func main() {
    addOneAndDouble := compose(addOne, double)
    result := addOneAndDouble(2)
    fmt.Println(result) // Output: 5
}

斐波那契数列

想要直接调用 printContentFile () 自动生成斐波那契数,就必须实现 read 接口,定义一个 type:函数。使其实现 Reader 接口。

//函数实现接口
//定义一个函数,使用type修饰。可以实现接口,也就是说只要是被type修饰的东西都可以实现接口。

type IntGen func() int

//实现read接口
func (g IntGen) Read(p []byte) (n int, err error) {
    next := g()

    if next > 10000 { //这里因为不设置退出会一直打印下去,所以做了限制
    return 0, io.EOF
    }
    s := fmt.Sprintf("%d\n", next)
    return strings.NewReader(s).Read(p)
}

func printContentFile(reader io.Reader) {
    scanner := bufio.NewScanner(reader)
    for scanner.Scan() { //
        println(scanner.Text())
    }
}

func fibonacci() IntGen {
    a := 0
    b := 1
    return func() int {
        a, b = b, a+b
        return a
    }
}

func main(){
    fun := fibonacci()
    printContentFile(fun)
}
相关推荐
究极无敌暴龙战神X几秒前
前端学习之ES6+
开发语言·javascript·ecmascript
虞书欣的66 分钟前
Python小游戏24——小恐龙躲避游戏
开发语言·python·游戏·小程序·pygame
源码121510 分钟前
ASP.NET MVC宠物商城系统
后端·asp.net·宠物
FHYAAAX13 分钟前
【机器学习】任务十:从函数分析到机器学习应用与BP神经网络
开发语言·python
汉克老师31 分钟前
GESP4级考试语法知识(贪心算法(四))
开发语言·c++·算法·贪心算法·图论·1024程序员节
爱吃生蚝的于勒1 小时前
C语言最简单的扫雷实现(解析加原码)
c语言·开发语言·学习·计算机网络·算法·游戏程序·关卡设计
Ai 编码助手1 小时前
Go语言 实现将中文转化为拼音
开发语言·后端·golang
hummhumm1 小时前
第 12 章 - Go语言 方法
java·开发语言·javascript·后端·python·sql·golang
hummhumm1 小时前
第 8 章 - Go语言 数组与切片
java·开发语言·javascript·python·sql·golang·database
何曾参静谧1 小时前
「QT」文件类 之 QDir 目录类
开发语言·qt