Ste*_*erg 166
简短的回答是它不会有效,因为转换为字符串需要完成字节数组的完整副本.这是正确的(非效率)方式来做你想要的:
buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
s := buf.String() // Does a complete copy of the bytes in the buffer.
Run Code Online (Sandbox Code Playgroud)
此副本作为保护机制完成.字符串是不可变的.如果您可以将[]字节转换为字符串,则可以更改字符串的内容.但是,go允许您使用不安全的软件包禁用类型安全机制.使用不安全的包裹需要您自担风险.希望这个名字是一个足够好的警告.以下是我将如何使用unsafe:
buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
b := buf.Bytes()
s := *(*string)(unsafe.Pointer(&b))
Run Code Online (Sandbox Code Playgroud)
我们走了,你现在已经有效地将你的字节数组转换为字符串.实际上,所有这一切都是欺骗类型系统将其称为字符串.这种方法有几点需要注意:
我的建议是坚持官方方法.做一个副本不是说贵,这是不值得的不安全的弊端.如果字符串太大而无法复制,则不应将其变为字符串.
Son*_*nia 93
到目前为止,答案还没有解决问题的"整个流"部分.我认为这样做的好方法是ioutil.ReadAll.有了你的io.ReaderCloser名字rc,我会写,
if b, err := ioutil.ReadAll(rc); err == nil {
return string(b)
} ...
Run Code Online (Sandbox Code Playgroud)
func copyToString(r io.Reader) (res string, err error) {
var sb strings.Builder
if _, err = io.Copy(&sb, r); err == nil {
res = sb.String()
}
return
}
Run Code Online (Sandbox Code Playgroud)
小智 5
最有效的方法是始终使用[]byte而不是string.
如果您需要打印从包中接收的数据io.ReadCloser,fmt包可以处理[]byte,但效率不高,因为fmt实现将在内部转换[]byte为string.为了避免这种转换,您可以实现fmt.Formatter类似的类型的接口type ByteSlice []byte.
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
Run Code Online (Sandbox Code Playgroud)