Go语言函数

函数是一种类型,可以赋值给变量或作为参数传递。例如:

// 定义一个函数类型

type Add func(a int, b int) int

 

// 定义一个符合该类型的函数

func add(a int, b int) int {

    return a + b

}

 

// 将函数赋值给变量

var f Add = add

 

// 将函数作为参数传递

func apply(op Add, a int, b int) int {

    return op(a, b)

}

 

fmt.Println(apply(f, 3, 4)) // 输出 7

Go 语言只有值传递一种方式,但是可以通过指针或接口来实现引用传递的效果。例如:

// 值传递,不会改变原始数据

func swap(a int, b int) {

    a, b = b, a

}

 

x := 1

y := 2

swap(x, y)

fmt.Println(x, y) // 输出 1 2


// 指针传递,可以改变原始数据

func swapByPointer(a *int, b *int) {

    *a, *b = *b, *a

}

 

x := 1

y := 2

swapByPointer(&x, &y)

fmt.Println(x,y) // 输出 2 1


// 接口传递,可以改变原始数据(如果接口的动态类型是指针)

type Swapper interface {

    Swap()

}

 

type Point struct {

    x int 

    y int 

}

 

func (p *Point) Swap() {

    p.x , p.y = p.y , p.x 

}

 

func swapByInterface(s Swapper) {

    s.Swap()

}

 

p := &Point{1 ,2}

swapByInterface(p)

fmt.Println(p.x , p.y ) // 输出 2 1 

Go 语言中有命名返回值和匿名返回值两种方式。例如:

// 命名返回值,可以省略 return 后面的表达式,但是可能导致歧义或错误。

func divide(a int ,b int ) (q ,r int ) {

    q = a / b 

    r = a % b 

    return // 等价于 return q ,r 

}

 

q ,r := divide(7 ,3)

fmt.Println(q,r ) // 输出 2 1 

 

func divideWithError(a int,b int)(q,r error){

   if(b ==0){

      r = errors.New("division by zero")

      return // 等价于 return q,r ,但是此时 q 是未初始化的零值。

   }

   q = a /b 

   return // 等价于 return q,r ,但是此时 r 是未初始化的零值。

}

defer 关键字和 panic/recover 函数在返回值处理中有特殊的作用。例如:

// defer 关键字可以在函数返回前执行一些操作,比如关闭文件、释放锁等。

func readFile(filename string)(content string,err error){

   file,err := os.Open(filename)

   if err != nil{

      return "",err 

   }

   defer file.Close() // 延迟关闭文件

   

   buf,err := ioutil.ReadAll(file)

   if err != nil{

      return "",err 

   }

   

   content = string(buf)

   

   return content,nil

}


// panic/recover 函数可以用于处理异常情况,比如数组越界、空指针等。

func safeDivide(a,b float64)(result float64,err error){

   

   defer func(){

      if e:= recover();e!=nil{

         err = fmt.Errorf("%v",e)// 捕获异常并转换为 error 类型。

      }

      

   }()

  if b == 0{

      panic("division by zero") // 抛出异常

   }

   

   result = a / b 

   

   return result,nil

   

}

 

result,err := safeDivide(10,0)

if err != nil{

   fmt.Println(err) // 输出 division by zero

}

延迟函数和闭包是 Go 语言中的高级特性,可以用于实现高阶函数或生成器等功能。例如:

// 延迟函数可以访问外部函数的局部变量,甚至修改它们。

func printNumbers() {

    i := 0

    defer fmt.Println(i) // 输出 0

    i++

    defer fmt.Println(i) // 输出 1

    return

}

 

printNumbers()


// 闭包是指能够捕获外部变量的匿名函数,可以用于实现高阶函数或生成器等功能。

func adder() func(int) int {

    sum := 0

    return func(x int) int {

        sum += x // 捕获外部变量 sum 

        return sum 

    }

}

 

f := adder()

fmt.Println(f(1)) // 输出 1 

fmt.Println(f(2)) // 输出 3 

fmt.Println(f(3)) // 输出 6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值