Skip to content

basics.go

文件信息

  • 📄 原文件:01_basics.go
  • 🔤 语言:go

完整代码

go
package main

import "fmt"

// ============================================================
//                      函数基础
// ============================================================
// Go 的函数是一等公民(first-class),可以:
// - 赋值给变量
// - 作为参数传递
// - 作为返回值
// - 在函数内部定义(匿名函数)

func main() {
	fmt.Println("=== 函数基础 ===")

	// ----------------------------------------------------------
	// 调用无参数无返回值的函数
	// ----------------------------------------------------------
	sayHello()

	// ----------------------------------------------------------
	// 调用有参数的函数
	// ----------------------------------------------------------
	greet("张三")
	greet("李四")

	// ----------------------------------------------------------
	// 调用有返回值的函数
	// ----------------------------------------------------------
	result := add(10, 20)
	fmt.Println("add(10, 20) =", result)

	// 可以直接使用返回值
	fmt.Println("add(3, 4) + add(5, 6) =", add(3, 4)+add(5, 6))

	// ----------------------------------------------------------
	// 调用多参数同类型的函数
	// ----------------------------------------------------------
	sum := addThree(1, 2, 3)
	fmt.Println("addThree(1, 2, 3) =", sum)

	// ----------------------------------------------------------
	// 函数作为值
	// ----------------------------------------------------------
	fmt.Println("\n=== 函数作为值 ===")

	// 将函数赋值给变量
	// 【重要】注意:是 add 而不是 add(),后者是调用
	var myFunc func(int, int) int = add
	fmt.Println("myFunc(100, 200) =", myFunc(100, 200))

	// 短声明
	anotherFunc := add
	fmt.Println("anotherFunc(5, 5) =", anotherFunc(5, 5))

	// ----------------------------------------------------------
	// 函数类型
	// ----------------------------------------------------------
	fmt.Println("\n=== 函数类型 ===")

	// 定义函数类型(通常在包级别定义)
	type Calculator func(int, int) int

	var calc Calculator = add
	fmt.Println("calc(50, 30) =", calc(50, 30))

	// 可以重新赋值为其他相同签名的函数
	calc = multiply
	fmt.Println("calc(50, 30) =", calc(50, 30))

	// ----------------------------------------------------------
	// 函数作为参数
	// ----------------------------------------------------------
	fmt.Println("\n=== 函数作为参数 ===")

	// 将函数作为参数传递给另一个函数
	result1 := compute(10, 5, add)
	result2 := compute(10, 5, subtract)
	result3 := compute(10, 5, multiply)

	fmt.Println("compute(10, 5, add) =", result1)
	fmt.Println("compute(10, 5, subtract) =", result2)
	fmt.Println("compute(10, 5, multiply) =", result3)

	// ----------------------------------------------------------
	// 函数作为返回值
	// ----------------------------------------------------------
	fmt.Println("\n=== 函数作为返回值 ===")

	// 获取一个函数作为返回值
	adder := getOperation("add")
	subber := getOperation("subtract")

	fmt.Println("adder(100, 30) =", adder(100, 30))
	fmt.Println("subber(100, 30) =", subber(100, 30))

	// ----------------------------------------------------------
	// 立即调用
	// ----------------------------------------------------------
	fmt.Println("\n=== 立即调用 ===")

	// 获取函数后立即调用
	fmt.Println("getOperation(\"multiply\")(6, 7) =", getOperation("multiply")(6, 7))

	main02()
	main03()
	main04()
	main05()
}

// ============================================================
//                      函数定义
// ============================================================

// ----------------------------------------------------------
// 无参数无返回值
// ----------------------------------------------------------
// 语法: func 函数名() { 函数体 }
// 【注意】Go 没有 void 关键字,不写返回类型即表示无返回值
func sayHello() {
	fmt.Println("Hello, World!")
}

// ----------------------------------------------------------
// 有参数无返回值
// ----------------------------------------------------------
// 语法: func 函数名(参数名 类型) { 函数体 }
// 【注意】类型在参数名后面(与 C/Java 相反)
func greet(name string) {
	fmt.Println("Hello,", name)
}

// ----------------------------------------------------------
// 有参数有返回值
// ----------------------------------------------------------
// 语法: func 函数名(参数名 类型) 返回类型 { 函数体 }
// 【注意】必须有 return 语句
func add(a int, b int) int {
	return a + b
}

// ----------------------------------------------------------
// 多参数同类型简写
// ----------------------------------------------------------
// 连续多个参数类型相同时,可以只写最后一个类型
// func add(a, b int) 等价于 func add(a int, b int)
func addThree(a, b, c int) int {
	return a + b + c
}

// ----------------------------------------------------------
// 更多运算函数(用于演示)
// ----------------------------------------------------------
func subtract(a, b int) int {
	return a - b
}

func multiply(a, b int) int {
	return a * b
}

// ----------------------------------------------------------
// 高阶函数:接收函数作为参数
// ----------------------------------------------------------
// 【定义】接收函数作为参数或返回函数的函数称为高阶函数
// 【用途】实现回调、策略模式、函数式编程风格
func compute(a, b int, operation func(int, int) int) int {
	return operation(a, b)
}

// ----------------------------------------------------------
// 高阶函数:返回函数
// ----------------------------------------------------------
// 【用途】工厂模式、闭包、延迟计算
func getOperation(op string) func(int, int) int {
	switch op {
	case "add":
		return add
	case "subtract":
		return subtract
	case "multiply":
		return multiply
	default:
		// 返回一个默认函数
		return func(a, b int) int {
			return 0
		}
	}
}

// ============================================================
//                      重要注意事项
// ============================================================
//
// 1. 【参数传递】Go 的参数传递都是值传递(pass by value)
//    - 基本类型:复制值
//    - 切片/map/channel:复制引用(底层数据共享)
//    - 结构体:复制整个结构体
//    - 指针:复制指针地址
//
// 2. 【函数签名】函数签名 = 参数类型 + 返回类型
//    func(int, int) int  // 这是一个函数类型
//
// 3. 【函数命名】
//    - 小写开头:包内私有
//    - 大写开头:可导出(其他包可用)
//
// 4. 【不支持】
//    - 函数重载(overloading):同名不同参数
//    - 默认参数值
//    - 可选参数(但可用可变参数模拟)
//
// 5. 【init 函数】
//    - 特殊函数,包初始化时自动调用
//    - 一个包可以有多个 init
//    - 不能手动调用

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布