757 lines
20 KiB
Go
757 lines
20 KiB
Go
/*
|
||
03-variadic-functions.go - Go 语言可变参数函数详解
|
||
|
||
学习目标:
|
||
1. 掌握可变参数函数的语法
|
||
2. 理解可变参数的传递机制
|
||
3. 学会可变参数的实际应用
|
||
4. 了解可变参数的限制和注意事项
|
||
5. 掌握可变参数的最佳实践
|
||
|
||
知识点:
|
||
- 可变参数语法 (...type)
|
||
- 可变参数的传递和展开
|
||
- 空参数和单参数处理
|
||
- 可变参数与切片的关系
|
||
- 可变参数的类型限制
|
||
- 实际应用场景
|
||
*/
|
||
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言可变参数函数详解 ===\n")
|
||
|
||
// 演示基本可变参数函数
|
||
demonstrateBasicVariadicFunctions()
|
||
|
||
// 演示可变参数的传递
|
||
demonstrateVariadicParameterPassing()
|
||
|
||
// 演示可变参数与其他参数的组合
|
||
demonstrateVariadicWithOtherParams()
|
||
|
||
// 演示可变参数的类型处理
|
||
demonstrateVariadicTypeHandling()
|
||
|
||
// 演示可变参数的实际应用
|
||
demonstratePracticalApplications()
|
||
|
||
// 演示可变参数的高级用法
|
||
demonstrateAdvancedVariadicUsage()
|
||
|
||
// 演示可变参数的限制和注意事项
|
||
demonstrateVariadicLimitations()
|
||
}
|
||
|
||
// demonstrateBasicVariadicFunctions 演示基本可变参数函数
|
||
func demonstrateBasicVariadicFunctions() {
|
||
fmt.Println("1. 基本可变参数函数:")
|
||
|
||
// 数字求和
|
||
fmt.Printf(" 数字求和:\n")
|
||
fmt.Printf(" sum() = %d\n", sum())
|
||
fmt.Printf(" sum(1) = %d\n", sum(1))
|
||
fmt.Printf(" sum(1, 2, 3) = %d\n", sum(1, 2, 3))
|
||
fmt.Printf(" sum(1, 2, 3, 4, 5) = %d\n", sum(1, 2, 3, 4, 5))
|
||
|
||
// 字符串连接
|
||
fmt.Printf(" 字符串连接:\n")
|
||
fmt.Printf(" concat() = \"%s\"\n", concat())
|
||
fmt.Printf(" concat(\"Hello\") = \"%s\"\n", concat("Hello"))
|
||
fmt.Printf(" concat(\"Hello\", \" \", \"World\") = \"%s\"\n",
|
||
concat("Hello", " ", "World"))
|
||
fmt.Printf(" concat(\"Go\", \" is\", \" awesome\", \"!\") = \"%s\"\n",
|
||
concat("Go", " is", " awesome", "!"))
|
||
|
||
// 找最大值
|
||
fmt.Printf(" 找最大值:\n")
|
||
fmt.Printf(" max(1) = %d\n", max(1))
|
||
fmt.Printf(" max(3, 1, 4, 1, 5) = %d\n", max(3, 1, 4, 1, 5))
|
||
fmt.Printf(" max(10, 5, 8, 3, 9, 2, 7) = %d\n", max(10, 5, 8, 3, 9, 2, 7))
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateVariadicParameterPassing 演示可变参数的传递
|
||
func demonstrateVariadicParameterPassing() {
|
||
fmt.Println("2. 可变参数的传递:")
|
||
|
||
// 直接传递多个参数
|
||
fmt.Printf(" 直接传递多个参数:\n")
|
||
result1 := multiply(2, 3, 4, 5)
|
||
fmt.Printf(" multiply(2, 3, 4, 5) = %d\n", result1)
|
||
|
||
// 传递切片(需要展开)
|
||
fmt.Printf(" 传递切片(使用 ... 展开):\n")
|
||
numbers := []int{2, 3, 4, 5}
|
||
result2 := multiply(numbers...)
|
||
fmt.Printf(" numbers := %v\n", numbers)
|
||
fmt.Printf(" multiply(numbers...) = %d\n", result2)
|
||
|
||
// 混合传递
|
||
fmt.Printf(" 混合传递:\n")
|
||
result3 := multiply(1, 2)
|
||
moreNumbers := []int{3, 4, 5}
|
||
result4 := multiply(append([]int{1, 2}, moreNumbers...)...)
|
||
fmt.Printf(" multiply(1, 2) = %d\n", result3)
|
||
fmt.Printf(" 混合传递结果 = %d\n", result4)
|
||
|
||
// 空切片传递
|
||
fmt.Printf(" 空切片传递:\n")
|
||
var emptySlice []int
|
||
result5 := multiply(emptySlice...)
|
||
fmt.Printf(" multiply(emptySlice...) = %d\n", result5)
|
||
|
||
// 传递给其他可变参数函数
|
||
fmt.Printf(" 传递给其他可变参数函数:\n")
|
||
numbers2 := []int{10, 20, 30}
|
||
avg := average(numbers2...)
|
||
fmt.Printf(" average(%v) = %.2f\n", numbers2, avg)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateVariadicWithOtherParams 演示可变参数与其他参数的组合
|
||
func demonstrateVariadicWithOtherParams() {
|
||
fmt.Println("3. 可变参数与其他参数的组合:")
|
||
|
||
// 固定参数 + 可变参数
|
||
fmt.Printf(" 固定参数 + 可变参数:\n")
|
||
result1 := formatMessage("INFO", "User login", "successful", "from IP 192.168.1.1")
|
||
fmt.Printf(" %s\n", result1)
|
||
|
||
result2 := formatMessage("ERROR", "Database connection failed")
|
||
fmt.Printf(" %s\n", result2)
|
||
|
||
// 多个固定参数 + 可变参数
|
||
fmt.Printf(" 多个固定参数 + 可变参数:\n")
|
||
result3 := calculateWithOperation("add", 1, 2, 3, 4, 5)
|
||
fmt.Printf(" calculateWithOperation(\"add\", 1, 2, 3, 4, 5) = %.2f\n", result3)
|
||
|
||
result4 := calculateWithOperation("multiply", 2, 3, 4)
|
||
fmt.Printf(" calculateWithOperation(\"multiply\", 2, 3, 4) = %.2f\n", result4)
|
||
|
||
result5 := calculateWithOperation("average", 10, 20, 30, 40, 50)
|
||
fmt.Printf(" calculateWithOperation(\"average\", 10, 20, 30, 40, 50) = %.2f\n", result5)
|
||
|
||
// 带默认值的可变参数函数
|
||
fmt.Printf(" 带默认值的可变参数函数:\n")
|
||
config1 := createConfig("myapp")
|
||
fmt.Printf(" createConfig(\"myapp\") = %+v\n", config1)
|
||
|
||
config2 := createConfig("myapp", "debug=true", "port=8080", "timeout=30")
|
||
fmt.Printf(" createConfig with options = %+v\n", config2)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateVariadicTypeHandling 演示可变参数的类型处理
|
||
func demonstrateVariadicTypeHandling() {
|
||
fmt.Println("4. 可变参数的类型处理:")
|
||
|
||
// 不同类型的可变参数
|
||
fmt.Printf(" 字符串可变参数:\n")
|
||
joined := joinStrings(", ", "apple", "banana", "cherry", "date")
|
||
fmt.Printf(" joinStrings(\", \", \"apple\", \"banana\", \"cherry\", \"date\") = \"%s\"\n", joined)
|
||
|
||
// 接口类型的可变参数
|
||
fmt.Printf(" 接口类型的可变参数:\n")
|
||
printValues("混合类型:", 42, "hello", 3.14, true, []int{1, 2, 3})
|
||
|
||
// 结构体类型的可变参数
|
||
fmt.Printf(" 结构体类型的可变参数:\n")
|
||
person1 := Person{Name: "Alice", Age: 25}
|
||
person2 := Person{Name: "Bob", Age: 30}
|
||
person3 := Person{Name: "Charlie", Age: 35}
|
||
|
||
avgAge := calculateAverageAge(person1, person2, person3)
|
||
fmt.Printf(" 平均年龄: %.1f\n", avgAge)
|
||
|
||
// 函数类型的可变参数
|
||
fmt.Printf(" 函数类型的可变参数:\n")
|
||
add := func(a, b int) int { return a + b }
|
||
multiply := func(a, b int) int { return a * b }
|
||
subtract := func(a, b int) int { return a - b }
|
||
|
||
results := applyOperations(10, 5, add, multiply, subtract)
|
||
fmt.Printf(" applyOperations(10, 5, add, multiply, subtract) = %v\n", results)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePracticalApplications 演示可变参数的实际应用
|
||
func demonstratePracticalApplications() {
|
||
fmt.Println("5. 可变参数的实际应用:")
|
||
|
||
// 应用1: 日志记录
|
||
fmt.Printf(" 应用1 - 日志记录:\n")
|
||
logInfo("用户登录", "用户ID", 123, "IP地址", "192.168.1.1")
|
||
logError("数据库连接失败", "错误码", 1001, "重试次数", 3)
|
||
logDebug("缓存命中", "键", "user:123", "值", "Alice")
|
||
|
||
// 应用2: SQL 查询构建
|
||
fmt.Printf(" 应用2 - SQL 查询构建:\n")
|
||
query1 := buildSelectQuery("users", "name", "email", "age")
|
||
fmt.Printf(" %s\n", query1)
|
||
|
||
query2 := buildSelectQuery("products", "id", "name", "price", "category", "stock")
|
||
fmt.Printf(" %s\n", query2)
|
||
|
||
// 应用3: HTTP 路由注册
|
||
fmt.Printf(" 应用3 - HTTP 路由注册:\n")
|
||
registerRoute("GET", "/users", authMiddleware, loggingMiddleware, getUsersHandler)
|
||
registerRoute("POST", "/users", authMiddleware, validateMiddleware, createUserHandler)
|
||
|
||
// 应用4: 数据验证
|
||
fmt.Printf(" 应用4 - 数据验证:\n")
|
||
userData := map[string]interface{}{
|
||
"name": "Alice",
|
||
"email": "alice@example.com",
|
||
"age": 25,
|
||
}
|
||
|
||
errors := validateData(userData,
|
||
validateRequired("name"),
|
||
validateEmail("email"),
|
||
validateRange("age", 0, 150),
|
||
)
|
||
|
||
if len(errors) == 0 {
|
||
fmt.Printf(" 数据验证通过\n")
|
||
} else {
|
||
fmt.Printf(" 验证错误: %v\n", errors)
|
||
}
|
||
|
||
// 应用5: 配置合并
|
||
fmt.Printf(" 应用5 - 配置合并:\n")
|
||
defaultConfig := Config{Port: 8080, Debug: false, Timeout: 30}
|
||
userConfig := Config{Debug: true, MaxConnections: 100}
|
||
envConfig := Config{Port: 9090, Timeout: 60}
|
||
|
||
finalConfig := mergeConfigs(defaultConfig, userConfig, envConfig)
|
||
fmt.Printf(" 最终配置: %+v\n", finalConfig)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAdvancedVariadicUsage 演示可变参数的高级用法
|
||
func demonstrateAdvancedVariadicUsage() {
|
||
fmt.Println("6. 可变参数的高级用法:")
|
||
|
||
// 可变参数的递归处理
|
||
fmt.Printf(" 可变参数的递归处理:\n")
|
||
result1 := recursiveSum(1, 2, 3, 4, 5)
|
||
fmt.Printf(" recursiveSum(1, 2, 3, 4, 5) = %d\n", result1)
|
||
|
||
// 可变参数的函数式处理
|
||
fmt.Printf(" 可变参数的函数式处理:\n")
|
||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||
|
||
evenSum := reduceInts(filterInts(numbers, isEven)...)
|
||
fmt.Printf(" 偶数之和: %d\n", evenSum)
|
||
|
||
oddProduct := reduceInts(filterInts(numbers, isOdd)...)
|
||
fmt.Printf(" 奇数之和: %d\n", oddProduct)
|
||
|
||
// 可变参数的管道处理
|
||
fmt.Printf(" 可变参数的管道处理:\n")
|
||
pipeline := createPipeline(
|
||
func(x int) int { return x * 2 }, // 乘以2
|
||
func(x int) int { return x + 1 }, // 加1
|
||
func(x int) int { return x * x }, // 平方
|
||
)
|
||
|
||
for i := 1; i <= 3; i++ {
|
||
result := pipeline(i)
|
||
fmt.Printf(" pipeline(%d) = %d\n", i, result)
|
||
}
|
||
|
||
// 可变参数的选项模式
|
||
fmt.Printf(" 可变参数的选项模式:\n")
|
||
server1 := createServer("localhost",
|
||
withPort(8080),
|
||
withTimeout(30),
|
||
withDebug(true),
|
||
)
|
||
fmt.Printf(" 服务器1: %+v\n", server1)
|
||
|
||
server2 := createServer("0.0.0.0",
|
||
withPort(9090),
|
||
withMaxConnections(1000),
|
||
)
|
||
fmt.Printf(" 服务器2: %+v\n", server2)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateVariadicLimitations 演示可变参数的限制和注意事项
|
||
func demonstrateVariadicLimitations() {
|
||
fmt.Println("7. 可变参数的限制和注意事项:")
|
||
|
||
// 限制1: 可变参数必须是最后一个参数
|
||
fmt.Printf(" 限制1: 可变参数必须是最后一个参数\n")
|
||
fmt.Printf(" ✓ func example(a int, b ...string) - 正确\n")
|
||
fmt.Printf(" ✗ func example(a ...int, b string) - 错误\n")
|
||
|
||
// 限制2: 一个函数只能有一个可变参数
|
||
fmt.Printf(" 限制2: 一个函数只能有一个可变参数\n")
|
||
fmt.Printf(" ✗ func example(a ...int, b ...string) - 错误\n")
|
||
|
||
// 注意事项1: 可变参数是切片
|
||
fmt.Printf(" 注意事项1: 可变参数在函数内部是切片\n")
|
||
inspectVariadicParam(1, 2, 3, 4, 5)
|
||
|
||
// 注意事项2: 修改可变参数会影响原始切片
|
||
fmt.Printf(" 注意事项2: 修改可变参数可能影响原始数据\n")
|
||
originalSlice := []int{1, 2, 3, 4, 5}
|
||
fmt.Printf(" 修改前: %v\n", originalSlice)
|
||
modifyVariadicParam(originalSlice...)
|
||
fmt.Printf(" 修改后: %v\n", originalSlice)
|
||
|
||
// 注意事项3: 性能考虑
|
||
fmt.Printf(" 注意事项3: 性能考虑\n")
|
||
fmt.Printf(" - 传递大量参数时,切片展开可能有性能开销\n")
|
||
fmt.Printf(" - 考虑直接传递切片而不是可变参数\n")
|
||
|
||
// 注意事项4: 类型安全
|
||
fmt.Printf(" 注意事项4: 类型安全\n")
|
||
fmt.Printf(" - 可变参数必须是相同类型\n")
|
||
fmt.Printf(" - 使用 interface{} 可以接受不同类型,但失去类型安全\n")
|
||
|
||
// 最佳实践
|
||
fmt.Printf(" 最佳实践:\n")
|
||
fmt.Printf(" 1. 优先考虑切片参数而不是可变参数\n")
|
||
fmt.Printf(" 2. 可变参数适用于调用时参数数量不确定的场景\n")
|
||
fmt.Printf(" 3. 注意可变参数的性能影响\n")
|
||
fmt.Printf(" 4. 使用选项模式处理复杂的可选参数\n")
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// ========== 函数定义 ==========
|
||
|
||
// 基本可变参数函数
|
||
func sum(numbers ...int) int {
|
||
total := 0
|
||
for _, num := range numbers {
|
||
total += num
|
||
}
|
||
return total
|
||
}
|
||
|
||
func concat(strings ...string) string {
|
||
result := ""
|
||
for _, str := range strings {
|
||
result += str
|
||
}
|
||
return result
|
||
}
|
||
|
||
func max(numbers ...int) int {
|
||
if len(numbers) == 0 {
|
||
return 0
|
||
}
|
||
|
||
maximum := numbers[0]
|
||
for _, num := range numbers {
|
||
if num > maximum {
|
||
maximum = num
|
||
}
|
||
}
|
||
return maximum
|
||
}
|
||
|
||
func multiply(numbers ...int) int {
|
||
if len(numbers) == 0 {
|
||
return 0
|
||
}
|
||
|
||
result := 1
|
||
for _, num := range numbers {
|
||
result *= num
|
||
}
|
||
return result
|
||
}
|
||
|
||
func average(numbers ...int) float64 {
|
||
if len(numbers) == 0 {
|
||
return 0
|
||
}
|
||
|
||
total := sum(numbers...)
|
||
return float64(total) / float64(len(numbers))
|
||
}
|
||
|
||
// 固定参数 + 可变参数
|
||
func formatMessage(level string, messages ...string) string {
|
||
timestamp := "2024-01-01 12:00:00"
|
||
allMessages := strings.Join(messages, " ")
|
||
return fmt.Sprintf("[%s] %s: %s", timestamp, level, allMessages)
|
||
}
|
||
|
||
func calculateWithOperation(operation string, numbers ...int) float64 {
|
||
if len(numbers) == 0 {
|
||
return 0
|
||
}
|
||
|
||
switch operation {
|
||
case "add":
|
||
return float64(sum(numbers...))
|
||
case "multiply":
|
||
return float64(multiply(numbers...))
|
||
case "average":
|
||
return average(numbers...)
|
||
default:
|
||
return 0
|
||
}
|
||
}
|
||
|
||
type AppConfig struct {
|
||
Name string
|
||
Options map[string]string
|
||
}
|
||
|
||
func createConfig(name string, options ...string) AppConfig {
|
||
config := AppConfig{
|
||
Name: name,
|
||
Options: make(map[string]string),
|
||
}
|
||
|
||
for _, option := range options {
|
||
parts := strings.SplitN(option, "=", 2)
|
||
if len(parts) == 2 {
|
||
config.Options[parts[0]] = parts[1]
|
||
}
|
||
}
|
||
|
||
return config
|
||
}
|
||
|
||
// 类型处理函数
|
||
func joinStrings(separator string, strings ...string) string {
|
||
return strings.Join(strings, separator)
|
||
}
|
||
|
||
func printValues(prefix string, values ...interface{}) {
|
||
fmt.Printf(" %s ", prefix)
|
||
for i, value := range values {
|
||
if i > 0 {
|
||
fmt.Printf(", ")
|
||
}
|
||
fmt.Printf("%v", value)
|
||
}
|
||
fmt.Printf("\n")
|
||
}
|
||
|
||
type Person struct {
|
||
Name string
|
||
Age int
|
||
}
|
||
|
||
func calculateAverageAge(people ...Person) float64 {
|
||
if len(people) == 0 {
|
||
return 0
|
||
}
|
||
|
||
totalAge := 0
|
||
for _, person := range people {
|
||
totalAge += person.Age
|
||
}
|
||
|
||
return float64(totalAge) / float64(len(people))
|
||
}
|
||
|
||
func applyOperations(a, b int, operations ...func(int, int) int) []int {
|
||
results := make([]int, len(operations))
|
||
for i, op := range operations {
|
||
results[i] = op(a, b)
|
||
}
|
||
return results
|
||
}
|
||
|
||
// 实际应用函数
|
||
func logInfo(message string, keyValues ...interface{}) {
|
||
fmt.Printf(" [INFO] %s", message)
|
||
for i := 0; i < len(keyValues); i += 2 {
|
||
if i+1 < len(keyValues) {
|
||
fmt.Printf(" %v=%v", keyValues[i], keyValues[i+1])
|
||
}
|
||
}
|
||
fmt.Printf("\n")
|
||
}
|
||
|
||
func logError(message string, keyValues ...interface{}) {
|
||
fmt.Printf(" [ERROR] %s", message)
|
||
for i := 0; i < len(keyValues); i += 2 {
|
||
if i+1 < len(keyValues) {
|
||
fmt.Printf(" %v=%v", keyValues[i], keyValues[i+1])
|
||
}
|
||
}
|
||
fmt.Printf("\n")
|
||
}
|
||
|
||
func logDebug(message string, keyValues ...interface{}) {
|
||
fmt.Printf(" [DEBUG] %s", message)
|
||
for i := 0; i < len(keyValues); i += 2 {
|
||
if i+1 < len(keyValues) {
|
||
fmt.Printf(" %v=%v", keyValues[i], keyValues[i+1])
|
||
}
|
||
}
|
||
fmt.Printf("\n")
|
||
}
|
||
|
||
func buildSelectQuery(table string, columns ...string) string {
|
||
if len(columns) == 0 {
|
||
return fmt.Sprintf("SELECT * FROM %s", table)
|
||
}
|
||
return fmt.Sprintf("SELECT %s FROM %s", strings.Join(columns, ", "), table)
|
||
}
|
||
|
||
// 模拟中间件和处理器
|
||
func authMiddleware() { fmt.Printf(" - 认证中间件\n") }
|
||
func loggingMiddleware() { fmt.Printf(" - 日志中间件\n") }
|
||
func validateMiddleware() { fmt.Printf(" - 验证中间件\n") }
|
||
func getUsersHandler() { fmt.Printf(" - 获取用户处理器\n") }
|
||
func createUserHandler() { fmt.Printf(" - 创建用户处理器\n") }
|
||
|
||
func registerRoute(method, path string, handlers ...func()) {
|
||
fmt.Printf(" 注册路由: %s %s\n", method, path)
|
||
for _, handler := range handlers {
|
||
handler()
|
||
}
|
||
}
|
||
|
||
// 验证函数类型
|
||
type ValidationFunc func(map[string]interface{}) []string
|
||
|
||
func validateRequired(field string) ValidationFunc {
|
||
return func(data map[string]interface{}) []string {
|
||
if _, exists := data[field]; !exists {
|
||
return []string{fmt.Sprintf("字段 %s 是必需的", field)}
|
||
}
|
||
return nil
|
||
}
|
||
}
|
||
|
||
func validateEmail(field string) ValidationFunc {
|
||
return func(data map[string]interface{}) []string {
|
||
if email, ok := data[field].(string); ok {
|
||
if !strings.Contains(email, "@") {
|
||
return []string{fmt.Sprintf("字段 %s 不是有效的邮箱", field)}
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
}
|
||
|
||
func validateRange(field string, min, max int) ValidationFunc {
|
||
return func(data map[string]interface{}) []string {
|
||
if value, ok := data[field].(int); ok {
|
||
if value < min || value > max {
|
||
return []string{fmt.Sprintf("字段 %s 必须在 %d-%d 范围内", field, min, max)}
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
}
|
||
|
||
func validateData(data map[string]interface{}, validators ...ValidationFunc) []string {
|
||
var allErrors []string
|
||
for _, validator := range validators {
|
||
if errors := validator(data); errors != nil {
|
||
allErrors = append(allErrors, errors...)
|
||
}
|
||
}
|
||
return allErrors
|
||
}
|
||
|
||
// 配置合并
|
||
type Config struct {
|
||
Port int
|
||
Debug bool
|
||
Timeout int
|
||
MaxConnections int
|
||
}
|
||
|
||
func mergeConfigs(configs ...Config) Config {
|
||
result := Config{}
|
||
|
||
for _, config := range configs {
|
||
if config.Port != 0 {
|
||
result.Port = config.Port
|
||
}
|
||
if config.Debug {
|
||
result.Debug = config.Debug
|
||
}
|
||
if config.Timeout != 0 {
|
||
result.Timeout = config.Timeout
|
||
}
|
||
if config.MaxConnections != 0 {
|
||
result.MaxConnections = config.MaxConnections
|
||
}
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// 高级用法函数
|
||
func recursiveSum(numbers ...int) int {
|
||
if len(numbers) == 0 {
|
||
return 0
|
||
}
|
||
if len(numbers) == 1 {
|
||
return numbers[0]
|
||
}
|
||
return numbers[0] + recursiveSum(numbers[1:]...)
|
||
}
|
||
|
||
func filterInts(numbers []int, predicate func(int) bool) []int {
|
||
var result []int
|
||
for _, num := range numbers {
|
||
if predicate(num) {
|
||
result = append(result, num)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func reduceInts(numbers ...int) int {
|
||
return sum(numbers...)
|
||
}
|
||
|
||
func isEven(n int) bool { return n%2 == 0 }
|
||
func isOdd(n int) bool { return n%2 == 1 }
|
||
|
||
func createPipeline(functions ...func(int) int) func(int) int {
|
||
return func(input int) int {
|
||
result := input
|
||
for _, fn := range functions {
|
||
result = fn(result)
|
||
}
|
||
return result
|
||
}
|
||
}
|
||
|
||
// 选项模式
|
||
type Server struct {
|
||
Host string
|
||
Port int
|
||
Timeout int
|
||
Debug bool
|
||
MaxConnections int
|
||
}
|
||
|
||
type ServerOption func(*Server)
|
||
|
||
func withPort(port int) ServerOption {
|
||
return func(s *Server) {
|
||
s.Port = port
|
||
}
|
||
}
|
||
|
||
func withTimeout(timeout int) ServerOption {
|
||
return func(s *Server) {
|
||
s.Timeout = timeout
|
||
}
|
||
}
|
||
|
||
func withDebug(debug bool) ServerOption {
|
||
return func(s *Server) {
|
||
s.Debug = debug
|
||
}
|
||
}
|
||
|
||
func withMaxConnections(max int) ServerOption {
|
||
return func(s *Server) {
|
||
s.MaxConnections = max
|
||
}
|
||
}
|
||
|
||
func createServer(host string, options ...ServerOption) Server {
|
||
server := Server{
|
||
Host: host,
|
||
Port: 80,
|
||
Timeout: 10,
|
||
Debug: false,
|
||
}
|
||
|
||
for _, option := range options {
|
||
option(&server)
|
||
}
|
||
|
||
return server
|
||
}
|
||
|
||
// 限制和注意事项函数
|
||
func inspectVariadicParam(numbers ...int) {
|
||
fmt.Printf(" 可变参数类型: %T\n", numbers)
|
||
fmt.Printf(" 可变参数长度: %d\n", len(numbers))
|
||
fmt.Printf(" 可变参数容量: %d\n", cap(numbers))
|
||
fmt.Printf(" 可变参数值: %v\n", numbers)
|
||
}
|
||
|
||
func modifyVariadicParam(numbers ...int) {
|
||
if len(numbers) > 0 {
|
||
numbers[0] = 999 // 修改第一个元素
|
||
}
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 03-variadic-functions.go
|
||
|
||
学习要点:
|
||
1. 可变参数使用 ...type 语法,必须是函数的最后一个参数
|
||
2. 可变参数在函数内部是切片类型
|
||
3. 传递切片给可变参数函数需要使用 ... 展开操作符
|
||
4. 一个函数只能有一个可变参数
|
||
5. 可变参数提供了灵活的函数调用方式
|
||
|
||
可变参数的语法:
|
||
- 定义: func name(params ...type) { ... }
|
||
- 调用: name(arg1, arg2, arg3) 或 name(slice...)
|
||
- 内部: params 是 []type 类型的切片
|
||
|
||
常见应用场景:
|
||
1. 数学运算函数(求和、求积等)
|
||
2. 字符串处理函数
|
||
3. 日志记录函数
|
||
4. 配置和选项处理
|
||
5. 中间件和处理器链
|
||
6. 数据验证
|
||
7. SQL 查询构建
|
||
|
||
最佳实践:
|
||
1. 优先考虑切片参数,可变参数适用于调用便利性
|
||
2. 使用选项模式处理复杂的可选参数
|
||
3. 注意可变参数的性能影响
|
||
4. 保持函数签名的简洁性
|
||
5. 合理使用接口类型的可变参数
|
||
|
||
限制和注意事项:
|
||
1. 可变参数必须是最后一个参数
|
||
2. 一个函数只能有一个可变参数
|
||
3. 可变参数是切片,修改会影响原始数据
|
||
4. 大量参数时考虑性能影响
|
||
5. 类型必须相同(除非使用 interface{})
|
||
|
||
高级用法:
|
||
1. 函数式编程风格
|
||
2. 选项模式
|
||
3. 中间件模式
|
||
4. 管道处理
|
||
5. 递归处理
|
||
6. 配置合并
|
||
|
||
性能考虑:
|
||
1. 切片展开有一定开销
|
||
2. 大量参数时考虑直接传递切片
|
||
3. 避免在热点代码中过度使用
|
||
4. 考虑内存分配的影响
|
||
*/ |