英文:
Struct initialization and method declaration in Go
问题
我是Go的新手,对结构体非常好奇。让我们定义一个名为T
的结构体。
type T struct {
size int
}
- 我看到了不同类型的结构体初始化。它们有什么区别?
new(T) // 1
T{size:1} // 2
&T{size:1} // 3
- 还有两种类型的方法声明:
func (r *T) area() int // 1
func (r T) area() int // 2
哪种方式是正确的?
英文:
I am new of Go, and pretty curious of structs. Let's define a struct T
type T struct {
size int
}
-
I have seen different types of struct initialization. What are the differences?
new(T) // 1 T{size:1} // 2 &T{size:1} // 3
-
And the two types of method declarations:
func (r *T) area() int // 1 func (r T) area() int // 2
What should be the right way?
答案1
得分: 1
- 分配
new 和 &T{size:1} 返回 *T
T{size:1} 返回 T
内置函数 new 接受类型 T,运行时分配该类型的变量存储空间,并返回指向它的类型为 *T 的值。变量的初始化如初始值部分所述。
任何其他命名类型 T 的方法集包含所有接收者类型为 T 的方法。相应指针类型 *T 的方法集包含所有接收者类型为 *T 或 T 的方法(即它还包含 T 的方法集)。
var pt *T
var t T
func (r *T) area() int
你可以使用 pt.area() 或 t.area()
func (r T) area() int
你可以使用 t.area(),不能使用 pt.area()
通常我们使用 func(r *T) area() int
英文:
- allocation
new and &T{size:1} returns *T
T{size:1} return T
> The built-in function new takes a type T, allocates storage for a variable of that type at run time, and returns a value of type *T pointing to it. The variable is initialized as described in the section on initial values.
2.
> The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).
var pt *T
var t T
>func (r *T) area() int
you can use pt.area() or t.area()
> func (r T) area() int
you can use t.area(), can't use pt.area()
usually we use func(r *T) area() int
答案2
得分: 1
这里有不同的例子:
type Animal struct {
Legs int
Kingdom string
Carnivore bool
}
通过引用进行初始化
返回指向结构体的指针
var tiger = &Animal{4, "mammalia", true}
fmt.Println(tiger.Kingdom) // 输出 "mammalia"
func changeKingdom(a *Animal) {
a.Kingdom = "alien" // 修改原始结构体
}
changeKingdom(tiger)
fmt.Println(tiger.Kingdom) // 输出 "alien"
构造函数 New
初始化
返回一个零值的指针
var xAnimal = New(Animal)
fmt.Println(xAnimal.Kingdom) // 输出 ""
fmt.Println(xAnimal.Legs) // 输出 0
fmt.Println(xAnimal.Carnivore) // 输出 false
changeKingdom(xAnimal)
fmt.Println(xAnimal.Kingdom) // 输出 "alien"
通过值进行初始化(复制)
返回原始结构体的独立副本
var giraffe = Animal{4, "mammalia", false}
fmt.Println(giraffe.Kingdom) // 输出 "mammalia"
func changeKingdom(a Animal) {
a.Kingdom = "extraterrestrial"
}
changeKingdom(giraffe)
fmt.Println(giraffe) // 输出 "mammalia"
在使用结构体时,通常会使用指针而不是副本。
英文:
Here are different examples:
type Animal struct {
Legs int
Kingdom string
Carnivore bool
}
Initialization by reference
Return the pointer to the struct
var tiger = &Animal{4, "mammalia", true}
fmt.Println(tiger.Kingdom) // print "mammalia"
func changeKingdom(a *Animal) {
a.Kingdom = "alien" // modify original struct
}
changeKingdom(tiger)
fmt.Println(tiger.Kingdom) // print "alien"
Constructor New
Initializaiton
Return a pointer with zero-ed values
var xAnimal = New(Animal)
fmt.Println(xAnimal.Kingdom) // print ""
fmt.Println(xAnimal.Legs) // print 0
fmt.Println(xAnimal.carnivore) // print false
changeKingdom(xAnimal)
fmt.Println(xAnimal.Kingdom) // print "alien"
Initialization by value (copy)
Return a separate copy of the original struct
var giraffe = Animal{4, "mammalia", false}
fmt.Println(giraffe.Kingdom) // print "mammalia"
func changeKingdom(a Animal) {
a.Kingdom = "extraterrestrial"
}
changeKingdom(giraffe)
fmt.Println(giraffe) // print "mammalia"
More often you'll deal with pointers when using structs than the copies.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论