GO 函数式编程

1、函数式编程

1.1 函数与闭包

经典样例

func adder() func (value int) int{
  sum := 0
  return func(value int) int{
    sum += value
    return sum
  }
}

func main(){
  adder := adder()
  for i := 0; i < 10; i++{
    fmt.Println(adder(i))
  }
}

1.2 函数式编程 VS 函数指针

  • 函数是一等公民:参数、变量、返回值都可以是函数
  • 高阶函数
  • 函数 --> 闭包

1.2.1 “正统”函数式编程

  • 不可变性:不能有状态,只有常量和函数
  • 函数只能有一个参数

将样例改为“正统”函数式编程

type iAdder func(int) (int, iAdder)

func adder2(base int) iAdder{
  return func(v int) (int, iAdder){
    return base+v, adder2(base+v)
  }
}

func main(){
  a := adder2(0)
  for i := 0; i < 10; i++{
    var s int
    s, a = a(i)
    fmt.Println(s)
  }
}

1.2.2 闭包

在这里插入图片描述
这里的局部变量相当于v,而自由变量是返回函数之外的,也就是sum是一个自由变量。

1.2.2.1 python中的闭包

def adder():
  sum = 0
  def f(value):
    nonlocal sum
    sum += value
    return sum
  return f
  • python是原生支持闭包的
  • 使用___course___来查看闭包内容

1.2.2.2 c++中的闭包

// c++14
auto adder(){
  auto sum = 0;
  return [=] (int value) mutable{
    sum += value;
    return sum;
  }
}
  • 过去:stl或者boost都有类似库
  • c++11及以后:支持闭包

1.2.2.3 java中的闭包

Function<Integer, Integer> adder(){
  final Holder<Integer> sum = new Holder<>(0);
  return (Integer value) -> {
    sum.value += value;
    return sum.value;
  };
}
  • java1.8以后:使用Function接口和Lambda表达式来创建函数对象
  • java中函数不是一等公民,所以没有办法作为参数,变量等。
  • 匿名类或者Lambda表达式均支持闭包

函数式编程样例一

2.1 斐波那契数列

package main

import "fmt"

func fibonacci() func() int{
  var fib1 = int(0)
  var fib2 = int(1)
  return func() int{
    fib1, fib2 = fib2, fib1+fib2
    return fib1
  }
}

func main(){
  f := fibonacci()
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
}

2.2 为函数实现接口

package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)
type intGen func() int

func fibonacci() intGen {
	var fib1 = int(0)
	var fib2 = int(1)
	return func() int{
		fib1, fib2 = fib2, fib1+fib2
		return fib1
	}
}

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 printFibonacci(reader io.Reader){
	scanner := bufio.NewScanner(reader)

	for scanner.Scan(){
		fmt.Println(scanner.Text())
	}
}

func main(){
	f := fibonacci()
	printFibonacci(f)
}

2.3 使用函数遍历二叉树

package main

import (
	"fmt"
)

type Node struct{
	Value int
	Left, Right *Node
}

func (node *Node) Print(){
	fmt.Print(node.Value, " ")
}

func (node *Node) Traverse(){
	node.TraverseFunc(func (n *Node) {
		n.Print()
	})
	fmt.Print()
}

func (node *Node) TraverseFunc(f func(*Node)) {
	if node == nil{
		return
	}
	node.Left.Traverse()
	f(node)
	node.Right.Traverse()
}

func main(){
	var root = new(Node)
	root.Value = 0
	root.Left = &Node{2, nil, nil}
	root.Right = &Node{3, nil, nil}

	root.Left.Right = &Node{4, nil, nil}
	root.Right.Left = &Node{5, nil, nil}

	root.Traverse()
	nodeCount := 0
	root.TraverseFunc(func(node *Node){
		nodeCount++
	})
	fmt.Println("Node count=", nodeCount)
}

2.4 go语言闭包的应用

  • 更为自然,不需要修饰如何访问自由变量
  • 没有Lambda表达式,但是有匿名函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值