go - 缓冲长度礼仪
问题描述
我有一个礼仪问题。我正在实现一个 RPC 服务器,这就是为什么这个函数需要一个值并在其参数中使用一个外变量。此函数从 a 读取container/list
并填充一个普通数组缓冲区,以便通过 out 变量返回。
func (t *PersonalPlaylist) GetPlaylist(n int, reply *[]string) error {
t.listMutex.Lock()
bufLen := min(n, t.list.Len()) // mark
buf := make([]string, bufLen) // mark
e := t.list.Front()
for i := 0; i < n; i++ {
s := e.Value.(string)
buf[i] = fmt.Sprintf("String #%d: %s", i, s)
e = e.Next()
if e == nil {
break
}
}
*reply = buf
t.listMutex.Unlock()
return nil
}
[请注意,此函数应限制最大缓冲区大小。]
特别值得注意的是标记线。我正在尝试确定缓冲区是否应始终具有请求的大小(n)并且在实际数据之外为零/零填充,或者缓冲区是否有时应该比请求值短。
如果缓冲区始终是请求的大小,则调用此函数的代码可以使用它作为参数传递的值作为数组循环的一部分。但是,数组中的某些值可能为 nil,因此必须在每个循环中检查 nil:
for i := 0; i < n; i++ {
if reply[i] == nil {
break; // or continue
}
}
在另一种情况下,调用者无法确定缓冲区大小,len(reply)
而是必须调用,但可以在很大程度上保证所有值都不是零。
我倾向于按原样使用该函数,并使调用者不确定缓冲区的长度(同时仍保证最大可能的缓冲区大小);这主要是因为这是一个相对高级别的接口,随着我的继续开发只会变得更高。是否有我不知道此代码中断的约定?还是某种以某种方式推动这种或另一种方式的礼仪?
解决方案
每个 Go 程序员都会遇到io.Reader
. 这是一个例子,
for {
// io.Reader
n, err := r.Read(buf[:cap(buf)])
buf = buf[:n]
if err != nil {
// handle error
}
// process buf
for i := 0; i < len(buf); i++ {
// process byte
}
}
可以看到,返回的是实际读取的字节数,所以我们调整缓冲区的大小。然后我们可以使用len(buf)
要处理的字节数。
Go 没有类似 C 的空终止字符串。Go 字符串s
有一个长度len(s)
。
并非每种类型都有nil
价值。nil
仅对指针类型有用。您的示例似乎不起作用。
var reply *[]string
for i := 0; i < n; i++ {
// invalid operation: (*reply)[i] == nil (mismatched types string and nil)
if (*reply)[i] == nil {
break // or continue
}
}
推荐阅读
- c# - 为什么task.run在c#中不按执行顺序打印输出
- android - 操作模式和可访问性
- vb.net - 只强制一个 Asyc sub 实例
- android - 有没有办法设置 pubsub 订阅?
- android - 使用 Web 服务 VS 访问现有数据的前端计算在多个对象中获取相同数据的最佳实践?
- javascript - amchart 项目符号通过鼠标悬停更改背景颜色
- json - 如何使用 jq json 解析器获取整个父节点?
- java - Spring,AppEngine:在 AppEngine 的数据源中添加 postgresql url
- c - 分配给另一个函数的局部变量的自动存储类变量的地址
- c# - 如何在列表List中使用两种类型