为什么在Go中将引用分配给结构体?

huangapple go评论78阅读模式
英文:

Why assign a reference to a struct in go?

问题

我正在查看这个页面上的代码:

http://golang.org/pkg/net/http/

有一件事我不明白 - 在某个地方,一个新的结构被创建并像这样初始化:

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

为什么在创建这个结构时要使用&

我还阅读了这篇博客文章,结构体的初始化方式如下:

r := Rectangle{}

这两种方式有什么区别,我应该如何知道使用哪一种?

英文:

I'm having a look at the code at this page:

http://golang.org/pkg/net/http/

And there's one thing I don't understand - at some point, a new structure is created and initialized like this:

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

Why use & when creating this structure?

I've also read this blog post and structs are initialized like this:

r := Rectangle{}

What is the difference between both and how should I know which one to use?

答案1

得分: 11

差异在于变量的类型。

client := &http.Client{

创建了类型为*http.Client的client变量

client := http.Client{

创建了一个http.Client类型的client变量。

英文:

The difference is in the type of your variable.

client := &http.Client{

makes client of type *http.Client

while

client := http.Client{

builds a http.Client.

答案2

得分: 3

顶部的返回一个指针。这是Go语言的惯用法,而不是使用new关键字。第二个只是一个值对象。如果你需要一个指针,请使用顶部的方法。

查看effective go文档以了解更多信息

http://golang.org/doc/effective_go.html#allocation_new

英文:

The top one is returning a pointer. It is a Go idiom instead of using new. The second one is just a value object. If you need a pointer use the top.

Check the effective go doc for more about this

http://golang.org/doc/effective_go.html#allocation_new

答案3

得分: 3

在面向对象编程中,为了使对象具有动态生命周期(即不与当前函数调用绑定),它需要在当前堆栈帧之外的其他位置进行动态分配,因此您通过指针来操作对象。这是一个非常常见的模式,在许多面向对象的语言中,包括Java、Python、Ruby、Objective-C、Smalltalk、JavaScript等,您只能处理指向对象的指针,而不能处理“对象作为值”本身。(但是有些语言,如C++,允许您拥有“对象作为值”;它使用了RAII习语,增加了一些复杂性。)

Go语言并不是一种面向对象的语言,但是它能够定义自定义类型并定义在该自定义类型上操作的方法,可以非常类似于类和方法的工作方式。从“构造函数”函数返回类型的指针允许“对象”具有动态生命周期。

英文:

In object-oriented programming, in order for an object to have dynamic lifetime (i.e. not tied to the current function call), it needs to be dynamically allocated in a place other than the current stack frame, thus you manipulate the object through a pointer. This is such a common pattern that in many object-oriented languages, including Java, Python, Ruby, Objective-C, Smalltalk, JavaScript, and others, you can only deal with pointers to objects, never with an "object as a value" itself. (Some languages though, like C++, do allow you to have "objects as values"; it comes with the RAII idiom which adds some complexity.)

Go is not an object-oriented language, but its ability to define custom types and define methods that operates on that custom type, can be made to work very much like classes and methods. Returning a pointer to the type from the "constructor" function allows the "object" to have a dynamic lifetime.

答案4

得分: 0

当我们使用引用时,我们在整个程序运行时使用单个项目。即使我们将其分配给一个新变量或通过函数传递。但是当我们使用值时,我们会创建个别项目的新副本。

(根据golang约定,“引用”不是正确的词。在这里,“值的地址”可能更合适 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

因为我们从中创建了一个新变量,但仍然引用相同的数据。但是,如果我们使用值而不是引用,并保持代码的其余部分不变。

// 从
andy := &Employee{}
// 到
andy := Employee{}

这次的结果将是:

Andy

因为这次它们都是独立的项目,不再引用相同的数据。

英文:

When we use reference, we use a single item throughout the program runtime. Even if we assign that to a new variable or pass through a function. But when we use value, we make new copies of individual items.

( Reference is not right word according to golang convention. "Address of value" would be more appropriate here https://golang.org/ref/spec#Package_initialization )

An example will make it much clear I hope.

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)
}

The result of this code block would be:

Brad

As we made new variable from it but still referring to same data. But if we use value instead of reference and keep the rest of the code same.

// from 
andy := &Employee{}
// to
andy := Employee{}

This time the result would be:

Andy

As this time they both are individual items and not referring to same data anymore.

huangapple
  • 本文由 发表于 2013年2月3日 00:11:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/14663774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定