接收器命名一致性

huangapple go评论94阅读模式
英文:

Receiver naming consistency

问题

官方文档建议在所有地方都使用相同的接收者名称。但是,遵守这个建议真的有意义吗?

我的意思是,我想象一下像 func (first Foo) concat(second Foo) (combinded Foo) 这样的写法更具表达力,而 first 只在连接的上下文中有意义。如果我们不这样做,基本上就被迫使用一些不可知但无用的接收者命名,比如 f,浪费了自我说明代码的机会。

英文:

The official documentation recommands to use the same receiver name everywhere. But does it really make sense to comply with that?

I mean, I imagine something like func (first Foo) concat(second Foo) (combinded Foo) to be more expressive, while first does only make sense in that very context of concatenation. If we don't go that route, we're basically forced to resort to some agnostic but useless receiver naming like f, wasting an opportuniy for self-documenting code.

答案1

得分: 2

Go Wiki: 接收器名称:

方法的接收器名称应反映其身份;通常使用其类型的一个或两个字母缩写就足够了(例如“c”或“cl”表示“Client”)。不要使用诸如“me”、“this”或“self”之类的通用名称,这些标识符是面向对象语言中给方法赋予特殊含义的典型名称。在Go中,方法的接收器只是另一个参数,因此应相应地命名。接收器的名称不需要像方法参数那样具有描述性,因为其作用是显而易见的,不起文档目的。它可以非常简短,因为它将出现在类型的每个方法的几乎每一行中;熟悉使得简洁成为可能。同样要保持一致:如果你在一个方法中将接收器称为“c”,就不要在另一个方法中将其称为“cl”。

如果你只有一个方法,可能并不重要。但如果你的类型有很多(甚至可能有几十个)方法,如果你在所有方法中使用相同的接收器名称,这将有所帮助。这样阅读和理解起来更容易。

另外,如果你想要/必须从一个方法复制一些代码到另一个方法(重构),如果接收器名称相同,你只需复制/粘贴即可,无需开始编辑不同的名称。

还有Dave Cheney的《Practical Go: Real world advice for writing maintainable Go programs》:

> ### 2.4. 使用一致的命名风格
> 好的名称的另一个特性是可预测性。读者在第一次遇到一个名称时应能够理解其用途。当他们遇到一个_常见_的名称时,他们应该能够假设它的含义自上次看到它以来没有改变。
>
> 例如,如果你的代码传递一个数据库句柄,确保每次参数出现时都具有相同的名称。而不是使用d *sql.DBdbase *sql.DBDB *sql.DBdatabase *sql.DB的组合,而是统一使用类似于;
>
> db *sql.DB
>
> 这样做可以促进熟悉度;如果你看到一个db,你就知道它是一个*sql.DB,它要么在本地声明,要么由调用者提供。
>
> 类似的建议也适用于方法的接收器;在该类型的每个方法中使用相同的接收器名称。这样读者就更容易内化该接收器在该类型的所有方法中的使用。

还有一篇有趣的阅读:Neither self nor this: Receivers in Go

英文:

Go Wiki: Receiver Names:

> The name of a method's receiver should be a reflection of its identity; often a one or two letter abbreviation of its type suffices (such as "c" or "cl" for "Client"). Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that gives the method a special meaning. In Go, the receiver of a method is just another parameter and therefore, should be named accordingly. The name need not be as descriptive as that of a method argument, as its role is obvious and serves no documentary purpose. It can be very short as it will appear on almost every line of every method of the type; familiarity admits brevity. Be consistent, too: if you call the receiver "c" in one method, don't call it "cl" in another.

If you have a single method, it probably doesn't matter. If you have a type with many (maybe even dozens of methods), it does help if you use the same receiver name in all. It's much easier to read and understand.

Also if you want / have to copy some code from one method to another (refactoring), if the receiver name is the same, you can just do copy / paste and your done, you don't have to start editing the different names.

Also Dave Cheney: Practical Go: Real world advice for writing maintainable Go programs:

> ### 2.4. Use a consistent naming style
> Another property of a good name is it should be predictable. The reader should be able to understand the use of a name when they encounter it for the first time. When they encounter a common name, they should be able to assume it has not changed meanings since the last time they saw it.
>
> For example, if your code passes around a database handle, make sure each time the parameter appears, it has the same name. Rather than a combination of d *sql.DB, dbase *sql.DB, DB *sql.DB, and database *sql.DB, instead consolidate on something like;
>
> db *sql.DB
>
> Doing so promotes familiarity; if you see a db, you know it’s a *sql.DB and that it has either been declared locally or provided for you by the caller.
>
> Similar advice applies to method receivers; use the same receiver name every method on that type. This makes it easier for the reader to internalise the use of the receiver across the methods in this type.

Also an interesting reading: Neither self nor this: Receivers in Go

答案2

得分: 2

鉴于以下条件:1.你有一个好的方法名,2.从方法声明中可以很容易地确定接收者类型,大多数情况下,像f这样的简短名称是可以接受的。如果你需要区分接收者和参数,那么建议你使用普通函数而不是方法,因为显然接收者没有从方法名中得出的明显含义。

英文:

Given that 1. You have a good method name, 2. The receiver type is readily apparent from the method declaration, most of the time a short name like f is quite alright. In the case where you need to differentiate the receiver from a parameter, it suggests that you could use a regular function rather than a method, since apparently the receiver doesn't have an obvious meaning that follows from the method name.

huangapple
  • 本文由 发表于 2021年5月21日 17:29:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/67634218.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定