Closed Package
To see the concept of closures through an accumulator
Python closures
def fun1(): sum = 0 def fun2(v): nonlocal sum sum += v return sum return fun2 a = fun1()for i in range(10): print(a(i))
FUN1 returns is not a value, but a function fun2,a = fun2, so a (i) will print the value of sum, why sum has been added, why the value of the function can be brought outside the function body, which is the magic of closure, closure is a concept of discrete mathematics, Can take a look at the online explanation to deepen the impression
You can actually think of a closure as a class, sum is the attribute in the class, and Fun2 is the method of the class.
So fun2 can use SUM (free variable)
Java closures
static Function<Integer, Integer> adder() { final Holder<Integer> sum = new Holder<>(0); return (Integer value) -> { sum.value += value; return sum.value; }; }public static void main(String[] args) { Function a = adder(); for (int i = 0; i < 10; i++) { System.out.println(a.apply(i)); }}
A function in Java cannot be passed as a variable, but it can also be simulated. The adder here is actually a function object
In the above python
code sum
, there is a modifier, which indicates that it nonlocal
sum
is not a local variable, and it is directly final
decorated
Closures are functions that can read other functions ' internal variables. In JavaScript, for example, only sub-functions inside a function can read local variables, so closures can be understood as "functions defined inside a function". In essence, closures are bridges that connect functions inside and outside of functions
Go closures
func adder() func(int) int { sum := 0 return func(v int) int { sum += v return sum }}
But the orthodox functional programming is not so, the function is actually a system, we only care about, the entry (x) and the return value (y) is what, in fact, how the implementation of the inside we do not care, a lot of modern business code, actually do a lot of things in the function body, create a lot of variables and objects, This is actually called the ' side effect ' of the function
Or look at the accumulator.
// 正统的函数式编程// 只有常量和函数type iAdder func(int) (int, iAdder)func adder2(base int) iAdder { return func(i int) (int, iAdder) { return base + i, adder2(base + i) }}func main(){ a := adder2(0) for i := 0; i < 10; i++ { var s int s, a = a(i) fmt.Println(s) }}
Getting Started with functional programming
Fibonacci sequence
func fib() func() int { a, b := 1, 1 return func() int { a, b = b, a+b return a }}f := fib()for i := 0; i < 10; i++ { fmt.Println(f())}// 1 2 3 ... 55 89
This is the number of fib printed with print, which previously said the two basic interfaces of read and write.
Now let the FIB function implement a read interface, and then any method that can receive reader can output this fib number.
// 定义一个函数的结构体,用函数实现接口,函数和普通变量一样type intGen func() intfunc fib1() intGen { a, b := 1, 1 return func() int { a, b = b, a+b return a }}
Put the mouse on the Intgen, then right-click
Image
Image
Image
func (g intGen) Read(p []byte) (n int, err error) { // 下一个 fib 数 next := g() //fib 数读不完,需要有一个结束条件 if next > 1000 { return 0, io.EOF } // 底层找一个已经实现的 s := fmt.Sprintf("%d\n", next) return strings.NewReader(s).Read(p)}
Note has been written very clearly, let intgen this function structure to implement the reader interface, and so on will be able to write a receive reader parameters of the print function, the Intgen function as parameters passed in the
/**打印的方法让 fib 实现 Reader 接口,就可以用 print 方法打印了*/func printFileContents(reader io.Reader) { scanner := bufio.NewScanner(reader) for scanner.Scan() { fmt.Println(scanner.Text()) }}f1 := fib1()printFileContents(f1)// 1 2 3 5 8 13 21 34 ... 610 987
Goimports
A handy tool
Image
Ability to automatically organize imports
Remove useless, use, but system not, automatic go get
But the normal is not down, because the need to download
golang.org/x/tools/cmd/goimports
, while
golang.org
In the country is the wall
go get -v github.com/gpmgo/gopm
, GitHub is not on the wall at home, download gopm
this tool first
- Configuration
$ GOPATH:bin
gopm get -v -g -u golang.org/x/tools/cmd/goimports
gopm
Download Google's toolkit
go install golang.org/x/tools/cmd/goimports
Put the goimports
installation under $ gopath
Summarize
- A function is a class citizen and can be passed as a parameter to another function
- Originally a function can only print, but after rewriting, let him pass a function to come in, can do anything, extensibility is very strong (according to the function passed in to work)
- Recommend a book for functional programming
scip
All of the above code has been uploaded to GitHub and welcome to star
Https://github.com/yejunyu/golearn
Image