Object-oriented programming in Go — use "new" keyword or nah?

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

Object-oriented programming in Go -- use "new" keyword or nah?

问题

我正在学习Go语言,并且对以下代码有一个问题:

package main

import (
	"fmt"
)

type Vector struct {
	x, y, z int
}

func VectorFactory(x, y, z int) *Vector {
	return &Vector{x, y, z}
}

func main() {
	vect := VectorFactory(1, 2, 3)
	fmt.Printf("%d\n", (vect.x * vect.y * vect.z))
}

在这段代码中,我定义了一个名为Vector的类型,它包含了xyz三个字段。我还定义了一个名为VectorFactory的函数,它声明并返回一个指向Vector的指针。我使用这个函数创建了一个名为vect的新Vector

  • 这段代码是否有问题?我应该使用new关键字而不是构建一个Factory吗?
  • 在使用完Vector之后,我需要像在C++中那样使用delete吗?如果需要,应该如何操作?

谢谢。我还在等待我的Go书籍送到。

英文:

I am learning Go, and I have a question based on the following code:

package main

import (
	"fmt"
)

type Vector struct {
	x, y, z int
}

func VectorFactory(x,y,z int) *Vector {
	return &Vector{x, y, z}
}

func main() {
	vect := VectorFactory(1, 2, 3)
	fmt.Printf("%d\n", (vect.x * vect.y * vect.z))
}

Here I've defined a type Vector with x, y, and z, and I've defined function VectorFactory which declares a pointer to a Vector and returns that pointer. I use this function to create a new Vector named vect.

  • Is this bad code? Should I be using the new keyword rather than building a Factory?
  • Do I need to delete the Vector after using it, like in C++? If so, how?

Thanks. I'm still waiting for my Go book to be delivered.

答案1

得分: 2

首选使用NewThing而不是ThingFactory

除非有复杂的初始化过程,或者你有意不导出结构的某些部分,否则不要创建NewThing函数。通过使用标签,可以选择性地设置结构的部分,这并不复杂。复杂的情况是像“槽Q的值取决于槽Zorb的值是什么”的情况。未导出的结构字段可以用于信息隐藏,但应谨慎使用。

Go语言具有垃圾回收机制,任何未被引用的数据都有资格被回收。开始时不必担心这个问题,然后在确保清除对不再感兴趣的数据的引用时,确保避免意外存活(“意外存活”实质上相当于GC中的“内存泄漏”)。

如果你经常需要打印数据结构,请考虑为它们创建一个String方法(这与你所做的打印不完全对应,但可能对于向量来说通常更有用):

func (v Vector) String() string {
  return fmt.Sprintf("V<%d, %d, %d>", v.x, v.y, v.z);
}

除非“vect”对你来说确实有特殊含义,否则建议使用“v”或“vector”作为名称。

英文:

Prefer NewThing to ThingFactory.

Don't make a NewThing function, unless you have complex initialisation, or you're intentionally not exporting parts of a struct. Selectively setting only parts of a struct is not complex, that can be accomplished by using labels. Complex would be things like "the value of slot Q depends on what the value of slot Zorb is". Unexported struct fields can be useful for information hiding, but should be used with care.

Go is garbage-collected, any piece of data that is not referenced is eligible to be collected. Start out y not worrying about it, then get to a point where you ensure you clean up any reference to data you're no longer interested in so as to avoid accidental liveness ("accidental liveness" is essentially the GC equivalent of "memory leak").

If you expect to print your data structures frequently, consider making a String method for them (this is not exactly corresponding to the print you do, but might be generally more useful for a vector):

func (v Vector) String() string {
  return fmt.Sprintf(&quot;V&lt;%d, %d, %d&gt;&quot;, v.x v.y, v.z);
}

Unless "vect" really means something to you, prefer either "v" or "vector" as a name.

huangapple
  • 本文由 发表于 2015年11月19日 03:36:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/33788848.html
匿名

发表评论

匿名网友

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

确定