函数是Go语言的基本构建块,用于封装可重用的代码逻辑。
package main
import "fmt"
// 基本函数
func greet() {
fmt.Println("Hello, World!")
}
// 带参数的函数
func add(a int, b int) int {
return a + b
}
// 简化参数类型(相同类型)
func multiply(a, b int) int {
return a * b
}
func main() {
greet()
sum := add(3, 5)
product := multiply(4, 6)
fmt.Printf("和: %d, 积: %d\n", sum, product)
}
Go语言支持函数返回多个值,这是Go的一大特色。
// 返回多个值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}
func swap(x, y string) (string, string) {
return y, x
}
func main() {
// 接收多个返回值
result, err := divide(10, 2)
if err != nil {
fmt.Println("错误:", err)
} else {
fmt.Println("结果:", result)
}
// 交换变量
a, b := swap("hello", "world")
fmt.Println(a, b) // world hello
}
// 命名返回值
func calculate(a, b int) (sum, product int) {
sum = a + b
product = a * b
return // 裸返回,自动返回命名的变量
}
func getStats(numbers []int) (min, max, avg int) {
if len(numbers) == 0 {
return
}
min, max = numbers[0], numbers[0]
sum := 0
for _, num := range numbers {
if num < min {
min = num
}
if num > max {
max = num
}
sum += num
}
avg = sum / len(numbers)
return
}
func main() {
s, p := calculate(5, 3)
fmt.Printf("和: %d, 积: %d\n", s, p)
nums := []int{3, 7, 1, 9, 4}
min, max, avg := getStats(nums)
fmt.Printf("最小: %d, 最大: %d, 平均: %d\n", min, max, avg)
}
// 可变参数(...)
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func printInfo(prefix string, values ...interface{}) {
fmt.Print(prefix, ": ")
for _, v := range values {
fmt.Print(v, " ")
}
fmt.Println()
}
func main() {
// 传递任意数量的参数
fmt.Println(sum(1, 2, 3)) // 6
fmt.Println(sum(1, 2, 3, 4, 5)) // 15
// 传递切片
nums := []int{10, 20, 30}
fmt.Println(sum(nums...)) // 60
printInfo("数据", 1, "hello", 3.14, true)
}
package main
import "fmt"
func main() {
// 定义并立即调用
func() {
fmt.Println("匿名函数")
}()
// 赋值给变量
add := func(a, b int) int {
return a + b
}
fmt.Println(add(3, 4)) // 7
// 作为参数传递
numbers := []int{1, 2, 3, 4, 5}
result := filter(numbers, func(n int) bool {
return n%2 == 0
})
fmt.Println(result) // [2 4]
}
func filter(nums []int, fn func(int) bool) []int {
var result []int
for _, num := range nums {
if fn(num) {
result = append(result, num)
}
}
return result
}
闭包是引用了外部变量的函数。
// 计数器闭包
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
// 累加器闭包
func adder(initial int) func(int) int {
sum := initial
return func(x int) int {
sum += x
return sum
}
}
func main() {
// 每个闭包都有自己的状态
c1 := counter()
c2 := counter()
fmt.Println(c1()) // 1
fmt.Println(c1()) // 2
fmt.Println(c2()) // 1
// 累加器
acc := adder(10)
fmt.Println(acc(5)) // 15
fmt.Println(acc(10)) // 25
}
defer用于延迟函数调用,常用于资源清理。
package main
import (
"fmt"
"os"
)
func main() {
// defer会在函数返回前执行
defer fmt.Println("世界")
fmt.Println("你好")
// 输出: 你好 世界
// 多个defer按LIFO顺序执行
for i := 1; i <= 3; i++ {
defer fmt.Println(i)
}
// 输出: 3 2 1
}
// 实际应用:文件操作
func readFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close() // 确保文件被关闭
// 读取文件内容...
return nil
}
// defer捕获参数值
func deferExample() {
x := 10
defer fmt.Println("defer:", x) // 捕获当前值10
x = 20
fmt.Println("函数:", x)
// 输出: 函数: 20
// defer: 10
}
方法是带有接收者的函数,用于给类型添加行为。
package main
import (
"fmt"
"math"
)
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
// 值接收者方法
func (r Rectangle) Area() float64 {
return r.width * r.height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.width + r.height)
}
func (c Circle) Area() float64 {
return math.Pi * c.radius * c.radius
}
func main() {
rect := Rectangle{width: 10, height: 5}
fmt.Printf("面积: %.2f\n", rect.Area())
fmt.Printf("周长: %.2f\n", rect.Perimeter())
circle := Circle{radius: 5}
fmt.Printf("圆面积: %.2f\n", circle.Area())
}
type Counter struct {
count int
}
// 指针接收者可以修改接收者
func (c *Counter) Increment() {
c.count++
}
func (c *Counter) Decrement() {
c.count--
}
func (c Counter) Value() int {
return c.count
}
func main() {
counter := Counter{count: 0}
counter.Increment()
counter.Increment()
fmt.Println(counter.Value()) // 2
counter.Decrement()
fmt.Println(counter.Value()) // 1
}
| 特性 | 值接收者 | 指针接收者 |
|---|---|---|
| 修改接收者 | 不能 | 可以 |
| 性能 | 复制整个结构体 | 只复制指针 |
| 使用场景 | 小型结构体、不需修改 | 大型结构体、需要修改 |
package main
import "fmt"
// 函数类型
type Operation func(int, int) int
func add(a, b int) int {
return a + b
}
func multiply(a, b int) int {
return a * b
}
// 接受函数作为参数
func calculate(a, b int, op Operation) int {
return op(a, b)
}
// 高阶函数:返回函数
func makeMultiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}
func main() {
result1 := calculate(5, 3, add)
result2 := calculate(5, 3, multiply)
fmt.Println(result1, result2) // 8 15
double := makeMultiplier(2)
triple := makeMultiplier(3)
fmt.Println(double(5)) // 10
fmt.Println(triple(5)) // 15
}
// 阶乘
func factorial(n int) int {
if n <= 1 {
return 1
}
return n * factorial(n-1)
}
// 斐波那契数列
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
// 优化的斐波那契(使用缓存)
func fibonacciMemo(n int, memo map[int]int) int {
if n <= 1 {
return n
}
if val, ok := memo[n]; ok {
return val
}
memo[n] = fibonacciMemo(n-1, memo) + fibonacciMemo(n-2, memo)
return memo[n]
}
func main() {
fmt.Println(factorial(5)) // 120
fmt.Println(fibonacci(10)) // 55
memo := make(map[int]int)
fmt.Println(fibonacciMemo(40, memo)) // 快速计算
}
package main
import "fmt"
func Map(nums []int, fn func(int) int) []int {
result := make([]int, len(nums))
for i, v := range nums {
result[i] = fn(v)
}
return result
}
func Filter(nums []int, fn func(int) bool) []int {
var result []int
for _, v := range nums {
if fn(v) {
result = append(result, v)
}
}
return result
}
func Reduce(nums []int, initial int, fn func(int, int) int) int {
result := initial
for _, v := range nums {
result = fn(result, v)
}
return result
}
func main() {
nums := []int{1, 2, 3, 4, 5}
// Map: 每个元素乘以2
doubled := Map(nums, func(n int) int {
return n * 2
})
fmt.Println(doubled) // [2 4 6 8 10]
// Filter: 过滤偶数
evens := Filter(nums, func(n int) bool {
return n%2 == 0
})
fmt.Println(evens) // [2 4]
// Reduce: 求和
sum := Reduce(nums, 0, func(acc, n int) int {
return acc + n
})
fmt.Println(sum) // 15
}
type Server struct {
host string
port int
timeout int
}
type Option func(*Server)
func WithHost(host string) Option {
return func(s *Server) {
s.host = host
}
}
func WithPort(port int) Option {
return func(s *Server) {
s.port = port
}
}
func WithTimeout(timeout int) Option {
return func(s *Server) {
s.timeout = timeout
}
}
func NewServer(opts ...Option) *Server {
s := &Server{
host: "localhost",
port: 8080,
timeout: 30,
}
for _, opt := range opts {
opt(s)
}
return s
}
func main() {
server := NewServer(
WithHost("0.0.0.0"),
WithPort(9000),
WithTimeout(60),
)
fmt.Printf("%+v\n", server)
}