go入门快速学习笔记二:函数、数组与切片

1、函数

1.1、不支持重载,暂无泛型

普通函数

package main

import "fmt"

func main() {

   println("----------------")
   prt("你好")
   println("!!!!!!!!!!!!!!!!")
}

func prt(s string) {
   fmt.Printf("hello:%s",s)
}

func prt(s string,n int16) {
   fmt.Printf("hello:%s\n",s)
   fmt.Printf("n = %d",n)
}

1.2、可以有多个返回值

可以命名返回,也可非命名返回

package main

import "fmt"

var num int = 10
var numx2, numx3 int

func main() {

   println("----------------")
   numx2 , numx3 = getX2AndX3(num)
   PrintValues()
   numx2 , numx3 = getX2AndX3f(num)
   PrintValues()
}

func PrintValues() {
   fmt.Printf("num = %d,2x num = %d,3x num = %d\n", num, numx2, numx3)
}

func getX2AndX3(input int) (int, int) {
   return 2 * input, 3 * input
}

func getX2AndX3f(input int) (x2 int, x3 int) {
   x2 = 2 * input
   x3 = 3 * input
   return
}

1.2.1、使用空白符

能丢弃不需要的值

package main

import "fmt"
func main() {

   var i int
   var f float32
   i, _, f = PrintValues()
   fmt.Printf("int : %d ,float: %f \n", i, f)
}

func PrintValues() (int, int, float32) {
   return 2, 4, 5.31
}

1.2.2、改变外部变量

package main

import "fmt"

func main() {

   n := 0
   reply := &n
   Multiply(10, 5, reply)

   fmt.Println("multiply:", *reply)
}

func Multiply(a, b int, reply *int) {
   *reply = a * b
}

1.3、可变长参数

package main

import (
   "fmt"
)

func main() {

   x := min(1, 3, 2, 7)
   fmt.Printf("minmum is : %d\n", x)
   arr := []int{7, 9, 3, 5}
   x = min(arr...)
   fmt.Printf("minmum is : %d\n", x)
}

func min(a ...int) int {
   if len(a) == 0 {
      return 0
   }
   min := a[0]
   for _, v := range a {
      if v < min {
         min = v
      }
   }
   return min
}

1.4、defer和追踪

允许推迟执行所描述的语句,直到函数完成前

1.4.1、若是有多个defer,执行顺序类似出栈

package main

import "fmt"

func main() {
   function()
}

func function() {
   fmt.Printf("In function at the top\n")
   defer function1()
   defer function2()
   defer function3()
   fmt.Printf("In function at the bottom!\n")
}

func function1() {
   fmt.Printf("function1 !")
}
func function2() {
   fmt.Printf("function2 !")
}
func function3() {
   fmt.Printf("function3 !")
}

1.4.2、语句中有变量时,至此值是定死了,虽然执行可能在变量重新赋值之后,但是变量值是不会再变的

package main

import "fmt"

func main() {
   var a int = 2
   function(a)
}

func function(a int) {
   fmt.Printf("In function at the top,a=%d\n", a)
   defer function1(a)
   fmt.Printf("In function at the bottom,a=%d\n", a)
   a = 4
   fmt.Println(a)
}

func function1(a int) {
   fmt.Printf("function1 a = %d!", a)
}
// 结果:
// In function at the top,a=2
// In function at the bottom,a=2
// 4
// function1 a = 2!

1.4.3、常见应用场景

关闭文件流

open a file 
defer file.Close()

解锁

mu.Lock()
defer mu.Unlock()

打印最终报告

printHeader() 
defer printFooter()

关闭数据库连接

defer disconnectFromDB()

使用defer实现追踪

此函数非常明显的展示了defer的调用时机

package main

import "fmt"

func main() {
   b()
}
func b() {
   trace("b")
   defer untrace("b")
   fmt.Println("in b")
   a()
}

func a() {
   trace("a")
   defer untrace("a")
   fmt.Println("in a")
}

func trace(s string) {
   fmt.Println("entering:", s)
}

func untrace(s string) {
   fmt.Println("leaving:", s)
}

使用defer记录函数的参数与返回值

package main

import (
   "io"
   "log"
)

func func1(s string) (n int, err error) {
   defer func() {
      log.Printf("func1(%q) = %d, %v", s, n, err)
   }()
   return 7, io.EOF
}

func main() {
   func1("Go")
}

1.5、内置函数

go有一类不需要进行导入就能够直接使用的内置函数。

内置函数表:

名称

说明

close

用于管道通信

len、cap

len 用于返回某个类型的长度或数量(字符串、数组、切片、map 和管道);cap 是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)

new、make

new 和 make 均是用于分配内存:new 用于值类型和用户定义的类型,如自定义结构,make用于内置引用类型(切片、map 和管道)。它们的用法就像是函数,但是将类型作为参数:new(type)、make(type)。new(T) 分配类型 T 的零值并返回其地址,也就是指向类型 T的指针。它也可以被用于基本类型: v := new(int) 。make(T) 返回类型T 的初始化之后的值,因此它比 new 进行更多的工作;new() 是一个函数,不要忘记它的括号。

copy、append

用于复制和连接切片

panic、recover

两者均用于错误处理机制

print、println

底层打印函数,在部署环境中建议使用 fmt 包

complex、realimag

用于创建和操作复数

1.6、递归函数

Fibonacii数列

package main

import "fmt"

func main() {
   fmt.Println(Fibonacci(10))
}

func Fibonacci(n int) (res int) {
   if n <= 2 {
      res = 1
   } else {
      res = Fibonacci(n-1) + Fibonacci(n-2)
   }
   return
}

1.7、将函数作为参数

package main

import "fmt"

func main() {
   callback(1, Add)
}

func callback(y int, f func(int, int)) {
   f(y, 2)
}

func Add(a, b int) {
   fmt.Printf("The sum of %d and %d is:%d\n", a, b, a+b)
}

1.8、闭包

匿名函数赋给变量,然后调用

package main

import "fmt"

func main() {
   f()
}

func f() {
   for i := 0; i < 4; i++ {
      g := func(i int) {
         fmt.Printf("%d ", i)
      }
      g(i)
      fmt.Printf("- g is of type %T and has value %v\n", g, g)
   }
}

defer搭配匿名函数

常用来改变返回值

package main

import "fmt"

func main() {
   fmt.Println(f())
}

func f() (ret int) {
   defer func() {
      ret++
   }()
   return 1
}

1.8.1、应用闭包

将函数作为返回值,这里非常神奇啊,乍一看还有点没反应过来,他将函数作为返回值给到变量,变量函数(此刻拿到的是匿名函数)还能继续传参

package main

import "fmt"

func main() {
   p2 := Add2()
   fmt.Printf("call Add2 for 3 gives: %v\n", p2(3))
   TwoAdder := Adder(2)
   fmt.Printf("The result is: %v\n", TwoAdder(3))
}

func Add2() func(b int) int {
   return func(b int) int {
      return b + 2
   }
}

func Adder(a int) func(b int) int {
   return func(b int) int {
      return a + b
   }
}

闭包所写的斐波那契数列值得好好分析

package main

import "fmt"

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

func fibonacci1() func() int {
   back1, back2 := 0, 1
   return func() int {
      temp := back1
      back1, back2 = back2, back1 + back2
      return temp
   }
}

1.8.2计算函数执行时间

package main

import (
   "fmt"
   "time"
)

func main() {
   f := fibonacci1()
   start := time.Now()
   for i := 0; i < 10; i++ {
      fmt.Println(f())
   }
   end := time.Now()
   delta := end.Sub(start)
   fmt.Printf("this amount of time: %s\n", delta)
}

func fibonacci1() func() int {
   back1, back2 := 0, 1
   return func() int {
      temp := back1
      back1, back2 = back2, back1 + back2
      return temp
   }
}

1.8.3 妙哉、空间换时间,这斐波那契计算方法时间复杂度太高,而且有些重复计算

package main

import (
   "fmt"
   "time"
)

const LIM = 50
var fibs [LIM + 1]uint64
func main() {
   var result uint64 = 0
   start := time.Now()
   result = fibonacci2(LIM)
   fmt.Printf("fibonacci(%d) is: %d\n", LIM, result)

   end := time.Now()
   delta := end.Sub(start)
   fmt.Printf("this amount of time: %s\n", delta)
}

func fibonacci2(n int) (res uint64) {

   if fibs[n] != 0 {
      res = fibs[n]
      return
   }
   if n <= 1 {
      res = 1
   } else {
      res = fibonacci2(n-1) + fibonacci2(n-2)
   }
   fibs[n] = res
   return
}

func fibonacci1(n int) (res uint64) {
   if n <= 2 {
      res = 1
   } else {
      res = fibonacci1(n-1) + fibonacci1(n-2)
   }
   return
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿星_Alex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值