zoukankan      html  css  js  c++  java
  • Go语言学习笔记(八)

    函数进阶

    函数作用域

    1.全局变量,在程序整个生命周期都是有效的
    2.局部变量:函数内定义/语句块内定义

    变量可变性

    包内任何变量或者函数都是能访问的。包外的话,首字母大写是可导出的能够被其他包访问或调用。小写表示是私有的,不能被外部的包访问。同一个包内大小写的全局变量或者函数是能被直接调用的。

    跨包导入和调用:
      1: 导入:
    
      2: import (
    
      3: 	github.comapple_schoollisten1functioncalc"
    
      4: )
    
      5: 调用:
    
      6: calc.Add()
    
      7: calc.A
    匿名函数
      1: func add(a, b int) int {
    
      2: 	return a + b
    
      3: }
    
      4: func test(){
    
      5: 	f1 := add
    
      6: 	fmt.Printf("type of f1=%T
    ", f1)
    
      7: }
    
      8: func main() {
    
      9: 	test()
    
     10: }
      1: func test_1() {
    
      2: 	f1 := func(a, b int) int {
    
      3: 		return a + b
    
      4: 	}
    
      5: 	fmt.Printf("type of f1=%T
    ", f1)
    
      6: }

    defer中使用匿名函数,注意下面两种区别

      1: func test_2() {
    
      2: 	var i int = 0
    
      3: 	defer fmt.Printf("i=%d
    ", i) // defer里i=0传进去了
    
      4: 	i = 100
    
      5: 	return 
    
      6: }
    
      7: >>> i = 0
    
      8: 
    
      9: func test_3() {
    
     10: 	var i int = 0
    
     11: 	defer func() {
    
     12: 		fmt.Printf("defer i=%d
    ", i)
    
     13: 	} ()
    
     14: 	i = 100
    
     15: 	return 
    
     16: }
    
     17: >>> defer i=100

    函数作为参数

      1: func add(a, b int) int {
    
      2: 	return a + b
    
      3: }
    
      4: 
    
      5: func test_c(a, b int32) int32 {
    
      6: 	return a * b
    
      7: }
    
      8: 
    
      9: func sub(a, b int) int {
    
     10: 	return a - b
    
     11: }
    
     12: 
    
     13: func calc(a, b int,op func(int, int) int) int {
    
     14: 	return op(a, b)
    
     15: }
    
     16: 
    
     17: func test_4() {
    
     18: 	sum := calc(100, 300, add)
    
     19: 	sub := calc(100, 300, sub)
    
     20: 	su := calc(100, 300, test_c)
    
     21: 	fmt.Printf("sum=%d sub=%d
    ", sum, sub)
    
     22: }
    
     23: 

    闭包

    即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
    也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

    例子1:

      1: package main
    
      2: import "fmt"
    
      3: 
    
      4: func add(base int) func(int) int {
    
      5: 	return func(i int) int {
    
      6: 		base += i
    
      7: 		return base
    
      8: 	}
    
      9: }
    
     10: func main() {
    
     11: 	tmp1:= add(10)
    
     12: 	fmt.Println(tmp1(1), tmp1(2), tmp1(3))
    
     13: 	tmp2:= add(100)
    
     14: 	fmt.Println(tmp2(1), tmp2(2), tmp2(3))
    
     15: }
    
     16: >>> 11 13 16
    
     17: 101 103 106

    例子2:

      1: package main
    
      2: import (
    
      3: 	"fmt"
    
      4: 	"strings"
    
      5: )
    
      6: 
    
      7: func makeSuffix(suffix string) func(string) string {
    
      8: 	return func(name string) string {
    
      9: 		if !strings.HasSuffix(name, suffix) {
    
     10: 			return name + suffix
    
     11: 		}
    
     12: 		return name
    
     13: 	}
    
     14: }
    
     15: func main() {
    
     16: 	func1 := makeSuffixFunc(".bmp")
    
     17: 	func2 := makeSuffixFunc(".jpg")
    
     18: 	fmt.Println(func1("test"))
    
     19: 	fmt.Println(func2("test"))
    
     20: }
    
     21: 
    
     22: >>> test.bmp
    
     23: test.jpg

    用python3来写就是这样(比较容易理解)

      1: def makeSuffix(suffix):
    
      2: 	
    
      3: 	def func(name):
    
      4: 		if  not name.endswith(suffix):
    
      5: 			return name + suffix
    
      6: 	return func
    
      7: func = makeSuffix(".bmg")
    
      8: print(func("test"))

    例子3:

      1: func calc(base int) (func(int) int, func(int) int) {
    
      2: 	add:= func(i int) int {
    
      3: 		base += i
    
      4: 		return base
    
      5: 	}
    
      6: 	sub:= func(i int) int {
    
      7: 		base -= i
    
      8: 		return base
    
      9: 	}
    
     10: 	return add, sub
    
     11: }
    
     12: 
    
     13: func main() {
    
     14: 	f1, f2 := calc(10)
    
     15: 	fmt.Println(f1(1), f2(2))
    
     16: 	fmt.Println(f1(3), f2(4))
    
     17: 	fmt.Println(f1(5), f2(6))
    
     18: 	fmt.Println(f1(7), f2(8))
    
     19: }
    
     20: 
    
     21: >>> 11 9
    
     22: 12 8
    
     23: 13 7
    
     24: 14 6

    闭包的意义

    返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    在多线程下的闭包的副作用:(了解就行了)
      1: package main
    
      2: 
    
      3: import (
    
      4: 	"fmt"
    
      5: 	"time"
    
      6: )
    
      7: func main() {
    
      8: 	for i:=0;i<5;i++ {
    
      9: 		go func(){
    
     10: 			fmt.Println(i)
    
     11: 		} ()
    
     12: 	}
    
     13: 	time.Sleep(time.Second*1)
    
     14: }
    几次的输出结果你会发现不但数值不是固定的,而且居然还会打印出5。本来循环在i=5是就停止了,但是协程搞了鬼,这个后面再讲。
  • 相关阅读:
    Eclipse配置C++环境
    C++/C中的struct和typedef struct用法和区别
    推荐系统实践(项亮)— 第2章 利用用户行为数据
    推荐系统实践(项亮)— 第1章 好的推荐系统
    语录摘抄(二)
    语录摘抄(一)
    深度学习—BN的理解(一)
    代码题(63)— 字符串拷贝
    代码题(62)— 滑动窗口最大值
    目标检测 — NMS
  • 原文地址:https://www.cnblogs.com/haoqirui/p/10115103.html
Copyright © 2011-2022 走看看