[Updated every week]-(Issue 52): Functional programming in Go

Insert image description here

Reference address

  • https://hedzr.com/golang/fp/golang-functional-programming-in-brief/
  • https://silverrainz.me/blog/funtional-programming-in-go-generics.html
  • https://zhuanlan.zhihu.com/p/436468481

Functional Programming (FP), as a programming paradigm, has the advantages of statelessness, no side effects, concurrency-friendly, and high level of abstraction.

Go language is not a purely functional programming language, but it supports some functional programming features and ideas. Functional programming is a programming paradigm
whose core philosophy is to view computation as a combination of function applications, emphasizing the use of pure functions, immutability, and the avoidance of side effects.

Declarative programming: Functional programming tends to use a declarative style, focusing on "what to do" rather than "how to do it". By using function composition, pipe operators, etc., you can implement a declarative style in Go, making the code more readable, concise and maintainable.

  • Higher-order functions: Functions in the Go language are first-class citizens and can be passed to other functions as parameters or as return values. This allows us to write higher-order functions, i.e. functions that accept other functions as arguments or return functions.
  • Closure: Go language supports closure, which allows you to define functions inside functions and access variables of external functions. Closures are often used in functional programming to create immutable functions, or to capture some state and encapsulate it in a function.
  • Function combination: Function reuse and combination can be achieved by combining multiple functions together to form new functions. Function composition can be achieved using nested calls of functions, passing function parameters, and returning functions.
  • Pure function: A pure function refers to a function without side effects, that is, the return value of the function is determined only by the input and does not depend on external state. In Go, you can write pure functions by avoiding modifying variables and data outside the function and avoiding the use of global state.
  • Immutability: Try to avoid modifying incoming parameters or external variables in a function. Instead, create new data structures or use functions to return new results. This reduces side effects and increases code readability and maintainability.
  • Function chaining: By returning the object itself or other objects with the same method, the function chaining style can be achieved. This is commonly used in Go to build fluent API interfaces or operators.

Examples of higher-order functions:

Define a higher-order function mapInts that accepts a slice of integers and a function as arguments and applies the function to each element in the slice.

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]
}

Closure example:

Use a closure to create a counter function that increments the counter value each time the counter function is called.

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
}

Function composition example:

Define two functions addOne and double, and then combine them together to form a new function 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
}

Fibonacci Sequence

If you want to directly call printContentFile () to automatically generate Fibonacci numbers, you must implement the read interface and define a type: function. Make it implement the Reader interface.

//函数实现接口
//定义一个函数,使用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)
}


Guess you like

Origin blog.csdn.net/hmx224_2014/article/details/135356434