我正在查看此页面上的代码:
http://golang.org/pkg/net/http/
还有一件事我不明白 - 在某些时候,一个新的结构被创建和初始化是这样的:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
为什么&
在创建这个结构时使用?
我也读过这篇博文,结构是这样初始化的:
r := Rectangle{}
两者有什么区别,我应该如何知道使用哪一个?
我正在查看此页面上的代码:
http://golang.org/pkg/net/http/
还有一件事我不明白 - 在某些时候,一个新的结构被创建和初始化是这样的:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
为什么&
在创建这个结构时使用?
我也读过这篇博文,结构是这样初始化的:
r := Rectangle{}
两者有什么区别,我应该如何知道使用哪一个?
区别在于变量的类型。
client := &http.Client{
client
类型_*http.Client
尽管
client := http.Client{
构建一个http.Client
.
最上面的是返回一个指针。这是一个 Go 习惯用法,而不是使用 new。第二个只是一个值对象。如果您需要指针,请使用顶部。
查看有效的 go doc 了解更多信息
在面向对象编程中,为了使对象具有动态生命周期(即不绑定到当前函数调用),它需要动态分配到当前堆栈帧以外的位置,因此您可以通过指针来操作对象. 这是一种常见的模式,以至于在许多面向对象的语言中,包括 Java、Python、Ruby、Objective-C、Smalltalk、JavaScript 等,您只能处理指向对象的指针,而不能处理“作为值的对象”本身。(不过,有些语言,比如 C++,确实允许您将“对象作为值”;它带有 RAII 习语,这增加了一些复杂性。)
Go 不是一种面向对象的语言,但它能够定义自定义类型和定义对自定义类型进行操作的方法,可以使其非常像类和方法一样工作。从“构造函数”函数返回指向类型的指针允许“对象”具有动态生命周期。
当我们使用引用时,我们在整个程序运行时使用单个项目。即使我们将其分配给新变量或通过函数传递。但是,当我们使用价值时,我们会制作单个项目的新副本。
(Reference is not right word according to golang convention. "Address of value" would be more appropriate here
https://golang.org/ref/spec#Package_initialization)
我希望举个例子就很清楚了。
type Employee struct {
ID int
Name string
Address string
}
func main() {
andy := &Employee{}
andy.Name = "Andy"
brad := andy
brad.Name = "Brad"
fmt.Println(andy.Name)
}
此代码块的结果将是:
Brad
因为我们从中创建了新变量,但仍然引用相同的数据。但是如果我们使用值而不是引用并保持其余代码相同。
// from
andy := &Employee{}
// to
andy := Employee{}
这一次的结果是:
Andy
因为这次它们都是单独的项目,不再引用相同的数据。