假设我有一个类型type T int
,并且我想要定义一个逻辑来对这个类型进行操作。
我应该使用什么抽象以及何时使用?
发布于 2014-09-03 02:56:28
有些情况下,您倾向于使用方法:
x.Foo
修改X并不比Foo(x)
修改X更令人惊讶。struct
一部分的网络连接,或者通过指针或切片等在结构中写入。friend
的字段。type openWeatherMap
定义为带有方法的空结构,而不是函数,只是为了满足与其他非空结构实现相同的weatherProvider
接口。
有些地方您倾向于使用函数:
func NewFoo(...) (*Foo)
是一个函数,而不是一个方法。Go没有构造函数的概念,所以它必须是这样的。interface
或基本类型上添加方法(除非您使用type
使它们成为一个新类型)。因此,strings.Split
和reflect.DeepEqual
必须是函数。而且,io.Copy
必须是一个函数,因为它不能仅仅在Reader
或Writer
上定义一个方法。请注意,它们不会声明一个新类型(例如,strings.MyString
),以避免无法对基本类型执行方法。User
或Page
),这会损害可读性或组织,甚至会导致结构性问题(例如,如果更难避免循环进口)。从不改变接收方、访问未导出字段等方法中创建一个非方法,可能是将其代码“向上”移动到应用程序的更高层或"over“到另一种类型/包的重构步骤,或者独立功能只是它最自然的长期位置。(对于史蒂夫·弗兰西亚在谈论他的围棋错误时包括了雨果中的一个例子,我给出了一些建议。)http.ListenAndServe()
是一个包级函数,它生成一个普通的http.Server
并在其上调用ListenAndServe
。http.HandleFunc()
或template.Funcs()
中,或者注册go vet
检查等等。别逼我。main()
或init()
调用了一些助手,那么它们会更干净,或者您的私有函数不会查看任何对象字段,而且永远也不会。同样,如果在您的情况下,您没有从OO (àla type Application struct{...}
)中获得任何东西,那么您不必强迫它。当有疑问时,如果某物是导出API的一部分,并且有一个自然的选择来附加它的类型,那么就让它成为一个方法。但是,不要扭曲您的设计(将关注点拉到您可以分离的类型或包中),只是为了某种东西可以成为一种方法。Writer
s不WriteJSON
;如果它们实现了一个,就很难实现。相反,您可以通过其他地方的函数json.NewEncoder(w io.Writer)
将JSON功能添加到json.NewEncoder(w io.Writer)
中。
如果您仍然不确定,首先编写文档以便清晰地读取文档,然后使代码自然地读取(o.Verb()
或o.Attrib()
),然后按照感觉正确的方式进行,而不会过多地使用它,因为您通常可以稍后重新排列它。
发布于 2014-09-02 21:17:25
如果您正在操作对象的内部secrets
,请使用该方法
(T *t) func someLogic() {
t.mu.Lock()
...
}
如果使用对象的public interface
,则使用该函数
func somelogic(T *t) {
t.DoThis()
t.DoThat()
}
发布于 2014-09-03 03:32:05
如果要更改T对象,请使用
func (t *T) someLogic() {
// ...
}
如果您不更改T对象,并且希望使用原始对象方式,请使用
func (t T) someLogic() {
// ...
}
但是请记住,这将生成一个调用someLogic
的临时对象T
如果您喜欢c语言的方式,请使用
func somelogic(t T) {
t.DoThis()
t.DoThat()
}
或
func somelogic(t T) {
t.DoThis()
t.DoThat()
}
还有一件事,就是将var隐藏在golang中。
https://stackoverflow.com/questions/25632483
复制相似问题