当前位置: 首页 > news >正文

Go语言实现链式调用

在 Go 语言中实现链式调用(Method Chaining),可以通过让每个方法返回对象本身(或对象的指针)来实现。这样每次方法调用后可以继续调用其他方法。

示例:实现字符串的链式操作

假设你想对一个字符串连续执行 TrimSuffixTrimPrefixToUpper 等操作,可以自定义一个类型并为其定义方法:

1. 定义包装类型
type StringWrapper struct {value string
}// 构造函数
func NewStringWrapper(s string) *StringWrapper {return &StringWrapper{value: s}
}// 获取最终结果
func (sw *StringWrapper) String() string {return sw.value
}
2. 实现链式方法

每个方法返回 *StringWrapper,以便继续调用其他方法:

// TrimSuffix 链式调用
func (sw *StringWrapper) TrimSuffix(suffix string) *StringWrapper {sw.value = strings.TrimSuffix(sw.value, suffix)return sw // 返回自身指针
}// TrimPrefix 链式调用
func (sw *StringWrapper) TrimPrefix(prefix string) *StringWrapper {sw.value = strings.TrimPrefix(sw.value, prefix)return sw
}// ToUpper 链式调用
func (sw *StringWrapper) ToUpper() *StringWrapper {sw.value = strings.ToUpper(sw.value)return sw
}
3. 使用示例
func main() {s := NewStringWrapper("  hello, world!  ").TrimPrefix("  ").    // 去掉前缀空格TrimSuffix("!  ").   // 去掉后缀 "!  "ToUpper().           // 转为大写String()             // 获取最终结果fmt.Println(s) // 输出: "HELLO, WORLD"
}

更简洁的实现(直接扩展 string 类型)

Go 不允许直接为内置类型(如 string)添加方法,但可以通过类型别名实现:

type MyString stringfunc (ms MyString) TrimSuffix(suffix string) MyString {return MyString(strings.TrimSuffix(string(ms), suffix))
}func (ms MyString) TrimPrefix(prefix string) MyString {return MyString(strings.TrimPrefix(string(ms), prefix))
}func main() {result := MyString("  hello!  ").TrimPrefix("  ").TrimSuffix("!  ")fmt.Println(result) // 输出: "hello"
}

关键点

  1. 返回对象自身:每个方法返回 *StringWrapper 或类型别名,以支持链式调用。
  2. 不可变 vs 可变
    • 上例中 StringWrapper可变的(修改原对象)。
    • 若希望每次操作生成新对象(类似字符串的不可变性),可以返回新实例:
      func (sw StringWrapper) TrimSuffix(suffix string) StringWrapper {return StringWrapper{value: strings.TrimSuffix(sw.value, suffix)}
      }
      

实际应用场景

  • Builder 模式(如 strings.Builderbytes.Buffer)。
  • 流式 API 设计(如数据库查询构造器)。

通过链式调用,代码可以更流畅(Fluent Interface),但需注意避免过度使用导致调试困难。

http://www.dtcms.com/a/196543.html

相关文章:

  • 2025年第三届盘古石杯初赛(智能冰箱,监控部分)
  • Docker数据卷
  • docker迅雷自定义端口号、登录用户名密码
  • Elasticsearch 官网阅读之 Term-level Queries
  • 校园导游大模型介绍
  • 大模型学习:Deepseek+dify零成本部署本地运行实用教程(超级详细!建议收藏)
  • 2025最新软件测试面试题(含答案解析+文档)
  • 2025年EB SCI2区TOP,多策略改进黑翅鸢算法MBKA+空调系统RC参数辨识与负载聚合分析,深度解析+性能实测
  • 鸿蒙北向源码开发: 检查应用接口dts文件api规范性
  • vue使用Pinia实现不同页面共享token
  • win32相关(字符编码)
  • 【文本切割器】RecursiveCharacterTextSplitter参数设置优化指南
  • 机器学习-人与机器生数据的区分模型测试-数据处理1
  • JavaScript 的编译与执行原理
  • 基于Fashion-MNIST的softmax回归-直接运行
  • 第3章 自动化测试:从单元测试到硬件在环(HIL)
  • 电子电路:到底该怎么理解电容器的“通交流阻直流”?
  • ElasticSearch 8.x新特性面试题
  • 使用Maven部署WebLogic应用
  • Ubuntu 添加系统调用
  • React中useDeferredValue与useTransition终极对比。
  • Spring-boot初次使用
  • redis的pipline使用结合线程池优化实战
  • 精益数据分析(63/126):移情阶段的深度潜入——从用户生活到产品渗透的全链路解析
  • linux——mysql高可用
  • 用 CodeBuddy 打造我的「TextBeautifier」文本美化引擎
  • SEO 优化实战:ZKmall模板商城的 B2C商城的 URL 重构与结构化数据
  • Webpack DefinePlugin插件介绍(允许在编译时创建JS全局常量,常量可以在源代码中直接使用)JS环境变量
  • TCP/UDP协议原理和区别 笔记
  • RAGFlow Arbitrary Account Takeover Vulnerability