Go语言常见错误| 滥用getters/setters

Go语言常见错误| 滥用getters/setters

源自开发者
专注于提供关于Go语言的实用教程、案例分析、最新趋势,以及云原生技术的深度解析和实践经验分享。
67篇原创内容

在Go语言编程中,恰如其分地使用getters和setters是至关重要的。过度和不适当地使用它们可能导致代码冗余、可读性差和封装不当。在本文中,我们将深入探讨如何识别滥用getter和setter的情况,以及如何采取最佳实践来避免这些常见的Go错误。

理解Go中的封装

在开始之前,有必要了解Go语言中的封装原则。在许多面向对象的语言中,封装通常通过使用私有字段(private)和公共方法(public)(即getters和setters)来实现。然而,在Go中,并没有明确的“private”和“public”关键字,而是通过大写字母开头的标识符来表达公有(可导出的)成员,小写字母开头的标识符表示私有(非导出的)成员。

常见误区

误区一:为每个字段创建getter和setter

一个常见的错误是为结构体中的每个字段都创建getter和setter方法,即使它们不需要特殊逻辑来访问或修改。

例子:

type Person struct {
    name string
}

func (p *Person) GetName() string {
    return p.name
}

func (p *Person) SetName(name string) {
    p.name = name
}

如何避免:

在Go中,如果字段不需要特殊的访问控制,那么它们应该被直接暴露,而不是通过getter和setter。

改进后的例子:

type Person struct {
    Name string
}

误区二:getter和setter中的不必要逻辑

避免在getter和setter中增加不必要的逻辑,因为这些额外的步骤可能不是调用者预期的。

例子:

func (p *Person) GetName() string {
    return "Name: " + p.name // Unnecessary formatting
}

func (p *Person) SetName(name string) {
    p.name = strings.TrimSpace(name) // Unnecessary trimming
}

如何避免:

Getter应只返回值,setter应只设置值。如果需要对数据进行格式化或清理,请使用单独的方法来明确这些意图。

改进后的例子:

type Person struct {
    Name string
}

func (p *Person) SetName(name string) {
    p.Name = name
}

func (p *Person) FormattedName() string {
    return "Name: " + p.Name
}

func (p *Person) CleanName() {
    p.Name = strings.TrimSpace(p.Name)
}

误区三:setter方法返回值

在Go中,setter方法一般不应该有返回值,因为这可能会导致混乱。

例子:

func (p *Person) SetName(name string) bool {
    if name == "" {
        return false
    }
    p.name = name
    return true
}

如何避免:

将setter方法设计为void函数。如果需要错误处理,可以考虑返回error类型。

改进后的例子:

func (p *Person) SetName(name string) error {
    if name == "" {
        return errors.New("name cannot be empty")
    }
    p.Name = name
    return nil
}

误区四:违反Go语言的约定

在一些其他语言中,使用get和set前缀是普遍的命名约定。而在Go中,通常省略这些前缀,应遵循Go的简洁和直率的命名风格。

例子:

func (p *Person) GetAge() int {
    return p.age
}

func (p *Person) SetAge(age int) {
    p.age = age
}

如何避免:

简化方法名,避开get和set前缀,除非它们增加了方法的清晰性。

改进后的例子:

type Person struct {
    name string
    Age int
}

误区五:在简单转发的getter/setter中添加锁

在并发编程中,为了线程安全,可能会在getter和setter方法中添加锁。然而,这有时候其实是一个过度设计。

例子:

type ThreadSafePerson struct {
    name string
    mu sync.Mutex
}

func (p *ThreadSafePerson) GetName() string {
    p.mu.Lock()
    defer p.mu.Unlock()
    return p.name
}

func (p *ThreadSafePerson) SetName(name string) {
    p.mu.Lock()
    defer p.mu.Unlock()
    p.name = name
}

如何避免:

如果结构体是immutable的或者很少修改,那么简单的读写可能不需要锁。考虑结构体的使用场景,只在确实需要的时候加锁。

改进后的例子:

type ThreadSafePerson struct {
    Name string // Assume atomic or rarely changed fields
}

总结

在Go中避免滥用getters和setters需要对Go的封装原则有深入的理解。简化你的API,保持方法直白,遵循Go的命名规范,这样将让你的代码更加清晰和易于维护。

 

文章精选

Go语言常见错误| 意外的变量隐藏

Go语言常见错误| 不必要的代码嵌套

Go语言常见错误| 误用init函数

使用 Go 实现跨平台的蓝牙聊天室

Go 数据库操作全解析

深入理解 Go 中的 CGo 编程

Go 语言中使用切片而非数组的理由

高效团队的 Go 编码规范

 

点击关注并扫码添加进交流群领取「Go 语言」学习资料

图片

100个Go常见错误及如何避免 · 目录
上一篇Go语言常见错误| 误用init函数
阅读原文
阅读 1
 
 
 
 
 
 
 
 
posted @   技术颜良  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
历史上的今天:
2022-01-07 golang Gorm 运用及执行原生SQL
2022-01-07 Redis集群到集群迁移
2022-01-07 关于gorm多表联合查询(left join)
2022-01-07 Gin gorm
2021-01-07 解决问题:mysql 1040 too many connections
2019-01-07 Prometheus+AlertManager实现邮件报警
点击右上角即可分享
微信分享提示