英文:
Need help understanding exporting variables in Go
问题
我了解从Go之旅中得知,大写变量意味着可以被导出,而结构体中的小写变量则不能被导出。但是我想要实现另外一种效果。
在Java中,我可以定义一个名为Adult
的类,如下所示:
class Adult {
private int age;
void setAge(int x) {
if (x >= 18)
this.age = x;
}
}
在Go语言中,我了解可以通过以下方式实现类似的效果:
// adult.go
package main
type Adult struct {
age int // 将其设为小写,因此是私有的。我希望没有人会修改它。
}
func (a *Adult) setAge(x int) { // 只有setter方法
if x >= 18 {
a.age = x
}
}
然而,在我的main.go
中,我可以这样做:
package main
import "fmt"
func (a *Adult) getAge() *int { // 这应该是不可能的?
return &a.age
}
func main() {
var temp *Adult = new(Adult)
temp.setAge(24)
fmt.Println(*temp.getAge())
var this_age_should_be_hidden = temp.getAge() // 我该如何防止别人这样做?
*this_age_should_be_hidden = 5
fmt.Println(*temp.getAge())
}
这就引出了我提出这个问题的原因。如果我们将变量设为小写,那有什么意义呢?我们总是可以在结构体上定义方法来暴露未导出的变量吗?这不是在一开始就违背了将其设为小写的初衷吗?
另外,如何用Go的方式实现我在上面的Java版本中所做的事情?如何确保结构体的某些字段在类外部不能被设置为无效值?
英文:
I understand from the Go tour that upper case variables are meant to be exported, while lower case variables in a struct are not exported. But I am trying to achieve something else.
In Java, I could define a class Adult
, like so
class Adult
{
private int age;
void setAge(int x)
{
if (x >= 18)
this.age = x;
}
}
In GoLang, I understand I could do something similar like so:
//adult.go
package main
type Adult struct {
age int //Made this lowercase, therefore private. I expect no one messes with this.
}
func (a *Adult) setAge(x int) { //Setter only
if x >= 18 {
a.age = x
}
}
However, I can do this in my main.go
:
package main
import "fmt"
func (a *Adult) getAge() *int { // This shouldn't be possible?
return &a.age
}
func main() {
var temp *Adult = new(Adult)
temp.setAge(24)
fmt.Println(*temp.getAge())
var this_age_should_be_hidden = temp.getAge() //How do I prevent someone from doing this?
*this_age_should_be_hidden = 5
fmt.Println(*temp.getAge())
}
That brings me to the title of this question. If we lower case our variables, what is the point? Can we always define methods on the struct which would expose unexported variables? Doesn't that defeat the purpose of lowercasing it, in the first place?
Also, what would be the Go way to achieve what I have done in the Java version above? How can I ensure that certain fields of my structs are not set to invalid values outside the class?
答案1
得分: 3
私有字段将在包内部可用。
考虑以下情况,基于您的示例,但将Adult
放在自己的person
包中:
package person
type Adult struct {
age int //将其小写,因此是私有的。我不希望有人擅自更改它。
}
func (a *Adult) setAge(x int) { //仅为设置器
if x >= 18 {
a.age = x
}
}
如果在person
包内创建一个成年人,可以设置他的年龄。但是,无法从外部包设置年龄:
package main
func main() {
var a person.Adult{}
a.setAge(10) //不可能 - 方法是私有的
}
如果您需要使用设置器,您可能希望将它们大写,以便对外部包开放,这样您就可以这样做:
package main
func main() {
var a person.Adult{}
a.SetAge(10) //可用的方法
}
英文:
Private fields will be available within the package.
Consider the following, based on your example, but placing Adult
inside its own person
package :
package person
type Adult struct {
age int //Made this lowercase, therefore private. I expect no one messes with this.
}
func (a *Adult) setAge(x int) { //Setter only
if x >= 18 {
a.age = x
}
}
Should an adult be created inside person package, one could set his age. However, one would not be able to set the age from an external package :
package main
func main() {
var a person.Adult{}
a.setAge(10) //impossible - method is private
}
If you need to use setters, you might want to capitalize them to open them to external packages so that you can do :
package main
func main() {
var a person.Adult{}
a.SetAge(10) //available method
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论