在Go中,如果我们的类型具有启动某些循环机制的方法(轮询A并永远执行B),最好将其表达为:
// Run does stuff, you probably want to run this as a goroutine
func (t Type) Run() {
// Do long-running stuff
}
Run Code Online (Sandbox Code Playgroud)
并记录这可能是想作为goroutine启动(并让调用者处理)
或者从调用者隐藏它:
// Run does stuff concurrently
func (t Type) Run() {
go DoRunStuff()
}
Run Code Online (Sandbox Code Playgroud)
我是Go的新手,并且不确定惯例是否说调用者前缀为'go'或者当代码设计为运行异步时为他们执行.
我目前的观点是我们应该记录并给呼叫者一个选择.我的想法是,在Go中,并发性实际上并不是暴露接口的一部分,而是使用它的属性.这是正确的吗?
kwo*_*lfe 10
我对此有你的看法,直到我开始编写一个我希望并发的Web服务的适配器.我有一个go例程,必须启动它来解析从Web调用返回到通道的结果.绝对没有这种API可以在不将其用作go例程的情况下工作的情况.
然后我开始查看net/http这样的软件包.该包中存在强制并发.在接口级别记录它应该能够并发使用,但是默认实现自动使用go例程.
因为Go的标准库通常会在自己的包中触发go例程,所以我认为如果你的包或API保证它,你可以自己处理它们.
我目前的观点是我们应该记录并给呼叫者一个选择.
我倾向于同意你的观点.
由于Go使得同时运行代码变得如此容易,因此您应该尽量避免API中的并发性(这会迫使客户端同时使用它).相反,创建一个同步API,然后客户端可以选择同步或同时运行它.
几年前的一次演讲中讨论了这个问题:十二个最佳实践
特别是,幻灯片26显示的代码更像您的第一个示例.
我会将net/http包视为异常,因为在这种情况下,并发性几乎是强制性的.如果包在内部不使用并发,那么客户端代码几乎肯定必须.例如,http.Client(据我所知)不会启动任何goroutines.只有服务器这样做.
在大多数情况下,它将成为调用方代码的一行:
go Run() 要么 StartGoroutine()
同步API并不难同时使用,并为调用者提供了更多选项.
| 归档时间: |
|
| 查看次数: |
1124 次 |
| 最近记录: |