登录
首页 >  Golang >  Go问答

缓冲区长度礼仪

来源:stackoverflow

时间:2024-03-17 14:12:30 255浏览 收藏

在实现 RPC 服务器时,涉及到缓冲区长度礼仪的问题。需要决定缓冲区是否应始终与请求大小相匹配,即使实际数据较少,还是应该根据实际数据的大小进行调整。文章认为,缓冲区应该根据实际数据的大小进行调整,就像 io.Reader 的工作方式一样。这将避免调用者进行不必要的 nil 检查,并简化代码。此外,文章指出,Go 语言中没有空终止字符串,字符串长度由 len() 函数确定,并且 nil 值仅适用于指针类型。

问题内容

我有一个礼仪问题。我正在实现一个 rpc 服务器,这就是为什么这个函数需要一个值并在其参数中使用一个输出变量。该函数从 container/list 读取并填充普通数组缓冲区以通过输出变量返回。

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
    }
}

本篇关于《缓冲区长度礼仪》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>