go---使用函数的正确姿势

函数是一等公民,函数类型是一等的数据类型。

函数值是能被随意传播的独立逻辑组件。

package main

import (
	"fmt"
)

// 函数声明,名叫 Printer
// 参数:contents string
// 返回的结果列表:n int, err error
type Printer func(contents string) (n int, err error)

// 函数实现
func printToStd(contents string) (butesNum int, err error) {
	return fmt.Println(contents)
}

func main(){
	var p Printer
	p = printToStd   // 将函数作为一个普通值赋给变量
	p("something")
}

高阶函数

想通过编写 calculate 函数实现两个整数间的加减乘除运算,但希望两个整数和具体的操作由函数的调用方给出。

方案一:

package main

import (
	"fmt"
	"errors"
)

type operate func(x, y int) int

// 将函数作为参数传递
func calculate(x int, y int, op operate) (int, error) {
	if op == nil {
		return 0, errors.New("invalid operation")
	}
	return op(x, y), nil
}

func main(){
	x, y := 12, 23
	op := func(x, y int) int {
		return x + y
	}
	result, err := calculate(x, y, op)
	fmt.Printf("The result: %d (error: %v)\n", result, err)
	result, err = calculate(x, y, nil)
	fmt.Printf("The result: %d (error: %v)\n", result, err)
}

在这里插入图片描述
方案二:

package main

import (
	"fmt"
	"errors"
)

type operate func(x, y int) int

type calculateFunc func(x int, y int) (int, error)

// 将其它的函数作为结果返回
// 闭包:在一个函数中存在对外来标识符的引用
// genCalculator 内定义了一个匿名函数
// 该匿名函数为闭包函数,op 既不代表它的任何参数或结果,也不是它自己声明的,而是一个自由变量
// op 这个自由变量代表什么,不是在定义闭包函数时确定的,而是在 genCalculator 被调用时确定的
func genCalculator(op operate) calculateFunc {
	return func(x int, y int) (int, error) { 
		if op == nil {
			return 0, errors.New("invalid operation")
		}
		return op(x, y), nil
	}
}

func main(){
	x, y := 12, 23
	op := func(x, y int) int {
		return x + y
	}
	add := genCalculator(op)
	result, err := add(x, y)
	fmt.Printf("The result: %d (error: %v)\n", result, err)
}

参数传递

package main

import (
	"fmt"
)

func main(){
	// 参数为值类型:数组
	array1 := [3]string{"a", "b", "c"}
	fmt.Printf("The array: %v\n", array1)
	array2 := modifyArray(array1)
	fmt.Printf("The modified array: %v\n", array2)
	fmt.Printf("The original array: %v\n", array1)
	fmt.Println()

	// 参数为引用类型:切片、字典、通道
	slice1 := []string{"x", "y", "z"}
	fmt.Printf("The slice: %v\n", slice1)
	slice2 := modifySlice(slice1)
	fmt.Printf("The modified slice: %v\n", slice2)
	fmt.Printf("The original slice: %v\n", slice1)
	fmt.Println()

	// complexArray1 是一个数组,但其中的每个元素是一个切片
	// 改变一维,不会影响原值
	// 改变二维,会影响原值
	complexArray1 := [3][]string{
		[]string{"d", "e", "f"},
		[]string{"g", "h", "i"},
		[]string{"j", "k", "l"},
	}
	fmt.Printf("The complex array: %v\n", complexArray1)
	complexArray2 := modifyComplexArray(complexArray1)
	fmt.Printf("The modifed complex array: %v\n", complexArray2)
	fmt.Printf("The original complex array: %v\n", complexArray1)
}

func modifyArray(a [3]string) [3]string {
	a[1] = "x"
	return a
}

func modifySlice(a []string) []string {
	a[1] = "i"
	return a
}

func modifyComplexArray(a [3][]string) [3][]string {
	a[1][1] = "s"    
	a[2] = []string{"o", "p", "q"}  
	return a
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值