有时候需要复制(别名为“深拷贝”)一个 net.URL
对象。我的理解是,net.URL
可以通过简单地复制结构来安全地复制:
newUrl := *url
由于 net.URL
通常由指针处理,因此检查文档以查看对象是否包含内部指针是很正常的,在这种情况下,复制可能会变得棘手。net.URL
的内容如下:
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // host or host:port
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method); added in Go 1.5
ForceQuery bool // append a query ('?') even if RawQuery is empty; added in Go 1.7
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
}
所以确实有一个指针在那里。这促使人们想出了另一种复制 URL 的方法,例如 String
/ Parse
往返:
https://medium.com/@nrxr/quick-dirty-way-to-deep-copy-a-url-url-on-go-464312241de4
这里的技巧是,User *Userinfo
实际上是“不可变的”。这是在 Userinfo
中记录的:The Userinfo type is an immutable encapsulation of username and password [...]
。因此,鉴于这种不变性的保证,简单地复制一个 URL 示例来复制它是安全的。标准库也执行 URL 示例的复制操作,例如:
go/src/net/http/request.go
第 361 行中的 245409e
| | *r2=*r |
因此,这个问题的主题是:
- 我能否得到确认,复制 URL 是正确的方法,而不仅仅是当前实现的意外(因此,它受到 Go 1.0 兼容性的保证)?
- 我们是否应该更好地记录它,因为它往往对这个库的新来的读者来说令人困惑?要么明确说明复制它的正确方法,要么将“不可变”一词移动到
User *Userinfo
字段的内联文档中(或者两者都做?)。
5条答案
按热度按时间3mpgtkmj1#
这个文档更好吗?
euoag5mw2#
你好,@rasky。
确实安全,事实上,我是Medium帖子的作者,我在几周前合并的一个PR中使用了
newU := *u
方法:https://github.com/golang/go/pull/35578/files#diff-6c2d018290e298803c0c9419d8739885R824-R837jvlzgdj93#
相关评论#41733(评论) 由@rsc发表
我仍然不明白在URL文档中究竟有什么值得一提的。
这是一个关于数据的一般性质,如果你想在变异之前复制一份,你可以这样做:u2 := *u; mutate u2。
我仍然不明白在URL上这个操作需要多少次。
@ainar-g已经看到过,但这只是存在,而不是频率。
hi3rlvi24#
关于#41733存在一些令人困惑的地方,因为实际上在net/http内部有一个cloneURL函数,而不仅仅是一个u2 := *u的事情。然而,它并不是url.URL公共协议的一部分,原因不明。
moiiocjp5#
最近遇到了一个问题,没有好的方法来深度克隆一个URL。