英文:
How to elegantly or efficiently write a map to a http.ResponseWriter
问题
我在想如何以最优雅的方式将一个键值对表单编码映射写入http.ResponseWriter。
Respond(kv map[string]string) {
  for key, value := range kv {
    fmt.Fprintf(a.w, "%s:%s\n", key, value)
  }  
}
我必须遵循这种键值对格式:
键值对表单编码
键值对表单中的消息是一系列行。每行以一个键开始,后跟一个冒号,然后是与该键关联的值。行以单个换行符(UCS代码点10,“\n”)终止。键或值不能包含换行符,键也不能包含冒号。
在冒号或换行符之前或之后不能添加其他字符,包括空格。消息必须以UTF-8编码以生成字节字符串。
我考虑过使用encoding/csv,但那不是有点过度吗?
编辑: 我目前想到的解决方案。(感谢所有提供的答案)
http://godoc.org/github.com/kugutsumen/encoding/keyvalue
https://github.com/kugutsumen/encoding/tree/master/keyvalue
英文:
I was wondering what would be the most elegant way to write a Key Value Form
encoded map to a http.ResponseWriter.
Respond(kv map[string]string) {
  for key, value := range kv {
    fmt.Fprintf(a.w, "%s:%s\n", key, value)
  }  
}
I have to follow this Key-Value format:
> Key-Value Form Encoding
>
> A message in Key-Value form is a sequence of lines. Each line begins
> with a key, followed by a colon, and the value associated with the
> key. The line is terminated by a single newline (UCS codepoint 10,
> "\n"). A key or value MUST NOT contain a newline and a key also MUST
> NOT contain a colon.
>
> Additional characters, including whitespace, MUST NOT be added before
> or after the colon or newline. The message MUST be encoded in UTF-8 to
> produce a byte string.
I thought about using encoding/csv but isn't that a bit overkill?
Edit: What I came up with so far. (Thanks for all the suggested answers)
答案1
得分: 3
标准库提供了对此的支持:请查看 http://godoc.org/net/url#Values。
您可以这样做:
f := make(url.Values)
for k, v := range myMap {
    f.Set(k, v)
}
myOutput.WriteString(f.Encode())
英文:
The standard library provides support for this: Look at http://godoc.org/net/url#Values.
You can do something like:
f := make(url.Values)
for k, v := range myMap {
    f.Set(k, v)
}
myOutput.WriteString(f.Encode())
答案2
得分: 2
例如,
package main
import (
	"bufio"
	"bytes"
	"fmt"
	"io"
)
func WriteRespond(w io.Writer, kv map[string]string) error {
	var buf bytes.Buffer
	for k, v := range kv {
		buf.WriteString(k)
		buf.WriteByte(':')
		buf.WriteString(v)
		buf.WriteByte('\n')
		_, err := buf.WriteTo(w)
		if err != nil {
			return err
		}
	}
	return nil
}
func main() {
	kv := map[string]string{
		"k1": "v1",
		"k2": "v2",
	}
	var buf = new(bytes.Buffer)
	w := bufio.NewWriter(buf)
	err := WriteRespond(w, kv)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = w.Flush()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(buf.Bytes())
	fmt.Println(buf.String())
}
输出:
[107 49 58 118 49 10 107 50 58 118 50 10]
k1:v1
k2:v2
英文:
For example,
package main
import (
	"bufio"
	"bytes"
	"fmt"
	"io"
)
func WriteRespond(w io.Writer, kv map[string]string) error {
	var buf bytes.Buffer
	for k, v := range kv {
		buf.WriteString(k)
		buf.WriteByte(':')
		buf.WriteString(v)
		buf.WriteByte('\n')
		_, err := buf.WriteTo(w)
		if err != nil {
			return err
		}
	}
	return nil
}
func main() {
	kv := map[string]string{
		"k1": "v1",
		"k2": "v2",
	}
	var buf = new(bytes.Buffer)
	w := bufio.NewWriter(buf)
	err := WriteRespond(w, kv)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = w.Flush()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(buf.Bytes())
	fmt.Println(buf.String())
}
Output:
[107 49 58 118 49 10 107 50 58 118 50 10]
k1:v1
k2:v2
答案3
得分: 1
如果你想要在Go中将字符串写入任何Writer(包括http.ResponseWriter)而不使用fmt包,你可以使用bytes包来读取字符串并将其写入Writer。
下面的代码使用bytes.NewBufferString从key和value字符串创建一个Buffer,然后使用WriteTo函数将它们写入http.ResponseWriter。
package main
import (
	"bytes"
	"log"
	"net/http"
)
func main() {
	kv := map[string]string{"key1": "val1", "key2": "val2", "key3": "val3", "key4": "val4", "key5": "val5"}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		for key, value := range kv {
			kvw := bytes.NewBufferString(key + ":" + value + "\n")
			if _, err := kvw.WriteTo(w); err != nil {
				log.Fatal("Error: ", err)
			}
		}
	})
	if err := http.ListenAndServe("localhost:8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
将输出:
key1:val1
key2:val2
key3:val3
key4:val4
key5:val5
希望这符合你的要求。
编辑:你也可以使用strings包中的strings.Reader类型和相应的WriteTo函数。
英文:
If you want to write strings to any Writer in Go (including an http.ResponseWriter) without using the fmt package, you can use the bytes package to read the strings and write them to the Writer.
The code below creates a Buffer from the key and value strings using bytes.NewBufferString and then writes them to the http.ResponseWriter using the WriteTo function.
package main
import (
	"bytes"
	"log"
	"net/http"
)
func main() {
	kv := map[string]string{"key1": "val1", "key2": "val2", "key3": "val3", "key4": "val4", "key5": "val5"}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		for key, value := range kv {
			kvw := bytes.NewBufferString(key + ":" + value + "\n")
			if _, err := kvw.WriteTo(w); err != nil {
				log.Fatal("Error: ", err)
			}
		}
	})
	if err := http.ListenAndServe("localhost:8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
Will output:
>>key1:val1
key2:val2
key3:val3
key4:val4
key5:val5
Hopefully that's close to what you're after.
EDIT: You can also use the strings.Reader Type and the corresponding WriteTo function from the strings package.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论