如何從具有多個逗號分隔值的標頭獲取值。例如,具有多個值的golang http解析標頭
url := "https://accounts.google.com/.well-known/openid-configuration"
resp, err := http.Get(url)
field := resp.Header.Get("Cache-Control") // "public, max-age=3600"
在這種情況下,我想獲得max-age
值。我看到兩種情況:使用strings.Split()
,Trim()
和等
- (我認爲這不是個好主意)使用
bufio.Scanner
- 與
SplitFunc
(更好一點)
任何好的想法或最佳實踐?
編輯1.使用strings.FieldsFunc()
const input = " public,max-age=3000, anothercase "
sep := func(c rune) bool {
return c == ',' || c == ' '
}
values := strings.FieldsFunc(input, sep)
關於基準
BenchmarkTrim-4 2000000 861 ns/op 48 B/op 1 allocs/op
編輯2.使用Scaner()
因此,讓基準它
func ScanHeaderValues(data []byte, atEOF bool) (advance int, token []byte, err error) {
// Skip leading spaces.
var start int
for start = 0; start < len(data); start++ {
if data[start] != ' ' {
break
}
}
// Scan until comma
for i := start; i < len(data); i++ {
if data[i] == ',' {
return i + 1, data[start:i], nil
}
}
// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
if atEOF && len(data) > start {
return len(data), data[start:], nil
}
// Request more data.
return start, nil, nil
}
func BenchmarkScanner(b *testing.B) {
const input = " public,max-age=3000, anothercase "
scanner := bufio.NewScanner(strings.NewReader(input))
split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
advance, token, err = ScanHeaderValues(data, atEOF)
return
}
scanner.Split(split)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for scanner.Scan() {
// a := scanner.Text()
// b.Logf("%+v\n", a)
}
}
}
而且結果:
BenchmarkTrim-4 2000000 861 ns/op 48 B/op 1 allocs/op
BenchmarkScanner-4 50000000 21.2 ns/op 0 B/op 0 allocs/op
如果您有任何其他更好的解決辦法,我想看到它。
爲什麼'Split'和'Trim' /'TrimSpace'不是一個好主意? – JimB
@JimB我想我會得到更多的內存分配,我可以通過使用'Scanner'來避免。 – BBQTD
你不能使用任何簡單的字符串拆分,因爲緩存控制值可以使用帶引號的字符串語法,這將允許在一個值內使用「,」 –