Go语言中静态方法的等效性

12
假设在Java中,我有一个名为CryptoFormat的类,其中有一个名为getLegacyFormat()的静态方法。当我想要使用该方法时,只需要调用CryptoFormat.getLegacyFormat()即可。这很清楚,因为我知道方法来自哪里。
在Go语言中,没有静态方法。我不想只创建一个名为crypto_format.go的文件并在其中定义该方法。原因是每当我需要该方法时,我只需调用GetLegacyFormat(),但它不包含方法来自哪里的上下文。
我可以想到两种解决方法:
  1. 创建一个名为cryptoformat的单独包,并在其中将该方法定义为全局函数。这样,我需要为仅有几个方法而创建新的包。此外,每当我需要类似这样的静态方法时,都必须定义新的包。
  2. 定义一个名为cryptoFormat的结构体,其中包含GetLegacyFormat()方法。另外,定义一个公共变量CryptoFormat(指向结构体cryptoFormat的实例)。这样,我需要方法时可以调用CryptoFormat.GetLegacyFormat()。
我不确定哪种方法更好,或者是否有更好的方法。

1
如果没有选择器表达式,被调用的函数要么是作用域内的函数变量,要么是当前包中的函数。通常,这已经足够的上下文了。请注意,Go语言没有全局函数或变量。 - Charlie Tumahai
你说得对。我编辑了问题。 - Thanh Bui
知道被调用的函数是作用域内的函数变量或当前包中的函数可能在小包中还好。当包变大时,我认为需要一个特定的上下文。 - Thanh Bui
2个回答

11
我认为你提到的选项1是定义此类函数更惯用的方式,如果它们不需要任何状态来证明将它们绑定到底层结构是必要的。
如果您想拥有一些状态作为函数上下文,则选项2是正确的选择。
请注意,在Go中,函数是“一等公民”,因此您不需要像在Java中那样定义静态方法所需的类。
是的,如果您想要单独的命名空间,则需要定义单独的包(就像在Java中需要定义单独的类和/或包)。
如果您想使您的实现习惯用法,请建议查看Go标准库(选择几个包并探索它们如何实现其函数),以获得更好的结构化常规方式的感觉。

使用选项1,我的包中将有几个子包,这些子包将只包含一个文件。在Go语言中这种情况常见吗? - Thanh Bui
1
通常,您会尝试将与相同功能相关的函数和类型分组并放置在同一个包中,以便不会每个包只有一个函数。如果它们非常简单且不相关,则每个包可能很小,我认为这也不会不寻常。 - eugenioy

5
每当我需要该方法时,我只需调用GetLegacyFormat(),它不包含方法来自哪里的上下文。
因此,在函数名称中添加上下文。
GetLegacyCryptoFormat()

4
顺便说一下,你可能可以去掉前面的“Get”。 - andybalholm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接