golang 的 io.Copy 那一堆东西不符合一般的函数约定吧?

108 天前
 lysShub

可以同时返回 n>0 并且 err!=nil , 是历史遗留吗?

导致这段代码写得挺丑的 https://github.com/golang/go/blob/master/src/io/io.go#L431

2147 次点击
所在节点    Go 编程语言
14 条回复
AEnjoyable
108 天前
这没有什么问题。
返回值要返回啥都是开发者自己确定的。。。至于为什么不改,主要是怕谁引用了这逻辑,改了做不到向下兼容。
对了,你的主题发错分区了。
pkoukk
108 天前
我记忆里,go 似乎没有说过,不允许在 err!=nil 的时候返回有意义的值吧?
pkoukk
108 天前
@pkoukk 他们甚至直接在文档里告诉你,这么做是语言的特色,是允许的。
https://go.dev/doc/effective_go#functions
Trim21
108 天前
这个例子里没啥问题吧,copy 又不是原子操作,如果是 copy 了 n 个字节中途出错了呢
jworg
108 天前
我觉得这样做挺合理的啊,比如写磁盘,磁盘满了没能全写下去,得有一个错误,然后很难回退得有一个值标明干了多少事情。
sujin190
108 天前
这两个不同语义吧,谁说 n>0 就不会有 err 的
jworg
108 天前
比如 rust 的等同接口

pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
where
R: Read,
W: Write,

如果出错了,error 里取不到成功干了多少事,这时你该怎么办。
mainjzb
108 天前
这就是同时返回 有效值和 error 的唯一优点了。 (不然学 rust 合并成 result 了

设想以下场景:
传输 tcp 2G 数据,传到一半的时候异常断开连接了。
下次启动可以断点续传。
Leviathann
108 天前
@mainjzb 代数数据类型 可以任意组合 嵌套一下就能表达
Nitroethane
108 天前
这符合惯例吧,看看 Linux 的 `read(2)` 和 `write(2)` 就明白了
guanzhangzhang
107 天前
因为具体实现接口的存流的不一定一次能处理完数据,然后每次处理都可能出错
mizuki9
107 天前
我觉得设计没什么问题,但也没什么用处,既然出错了,写了一半的长度 n 应该没什么用,最多展示一下,搞续传什么的不现实
lysShub
106 天前
@mainjzb 可以把 size 携带在 error 里面
xfriday
91 天前
@jworg -> Result<usize, usize>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1132824

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX