在这篇短文中,我们将讨论如何在Go中添加、修改或删除URL查询字符串参数。为了说明问题,我们将看看如何改变这个URL:
https://example.com?name=alice&age=28&gender=female
至此:
https://example.com?name=alice&age=29&occupation=carpenter
如果你想在原地改变URL查询字符串:
// Use url.Parse() to parse a string into a *url.URL type. If your URL is
// already a url.URL type you can skip this step.
urlA, err := url.Parse("https://example.com?name=alice&age=28&gender=female")
if err != nil {
log.Fatal(err)
}
// Use the Query() method to get the query string params as a url.Values map.
values := urlA.Query()
// Make the changes that you want using the Add(), Set() and Del() methods. If
// you want to retrieve or check for a specific parameter you can use the Get()
// and Has() methods respectively.
values.Add("occupation", "carpenter")
values.Del("gender")
values.Set("age", strconv.Itoa(29))
// Use the Encode() method to transform the url.Values map into a URL-encoded
// string (like "age=29&name=alice...") and assign it back to the URL. Note
// that the encoded values will be sorted alphabetically based on the parameter
// name.
urlA.RawQuery = values.Encode()
fmt.Printf("urlA: %s", urlA.String())
运行这个将打印出来:
urlA: https://example.com?age=29&name=alice&occupation=carpenter
如果你想创建一个克隆的URL,但使用不同的查询字符串,同时保持原始URL不变,你需要先创建一个原始的 url.URL结构的副本。
有几种方法可以做到这一点。你可以重新解析URL,或者你可以解除对原始url.URL ,并制作一个副本,像这样:
// This is equivalent to: var newUrl url.URL = *originalUrl
newUrl := *originalUrl
当你这样做时,你创建了一个新的newURL 类型的变量url.URL ,它被初始化为*originalURL 的(被解除引用的)值。这意味着newURL 在内存中的地址与originalURL 不同。
把这些放在一起,创建一个具有不同参数的新URL的模式是:
urlA, err := url.Parse("https://example.com?name=alice&age=28&gender=female")
if err != nil {
log.Fatal(err)
}
// Make a copy of the original url.URL.
urlB := *urlA
// Make the param changes to the new url.URL type...
values := urlB.Query()
values.Add("occupation", "carpenter")
values.Del("gender")
values.Set("age", strconv.Itoa(29))
urlB.RawQuery = values.Encode()
fmt.Printf("urlA: %s\n", urlA.String()) // This will be unchanged.
fmt.Printf("urlB: %s\n", urlB.String()) // This will have the new params.
运行这个将打印出来:
urlA: https://example.com?name=alice&age=28&gender=female
urlB: https://example.com?age=29&name=alice&occupation=carpenter
顺便提一下,当你想 "克隆 "一个URL并对其进行修改时,你可以使用这种技术。例如,要创建一个具有不同路径的URL的克隆,你可以这样做:
urlA, err := url.Parse("https://example.com/foo")
if err != nil {
log.Fatal(err)
}
urlB := *urlA
urlB.Path = "/bar"
fmt.Printf("%s\n", urlA.String()) // Prints https://example.com/foo
fmt.Printf("%s\n", urlB.String()) // Prints https://example.com/bar