private/public fields in structs.. acting differently

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

private/public fields in structs.. acting differently

问题

为什么我可以这样做

package main

import "fmt"

func main() {
    c := Circle{x: 0, y: 0, r: 5}
    fmt.Println(c.r)
}

type Circle struct {
    x float64
    y float64
    r float64
}

http://play.golang.org/p/0ypcekVDV9

但是如果我尝试在一个包中访问一个具有小写字段的结构体,会返回编译器错误。

英文:

Why can I do this

package main

import "fmt"

func main() {
	c := Circle{x: 0, y: 0, r: 5}
	fmt.Println(c.r)
}

type Circle struct {
    x float64
    y float64
    r float64
}

http://play.golang.org/p/0ypcekVDV9

When I can't do the same with a struct in a package?

If I would try to access a struct with a field with lowercase a compiler error is returned..

答案1

得分: 4

如已经说明的那样,需要将字段导出以便从另一个包中访问。请参阅规范

导出的标识符

为了允许从另一个包中访问,可以将标识符导出。如果满足以下两个条件,则标识符被导出:

  • 标识符名称的第一个字符是一个 Unicode 大写字母(Unicode 类别 "Lu");
  • 标识符在包块中声明,或者是字段名或方法名。其他所有标识符都不会被导出。

如果你想保持字段的私有性,需要使用访问器(set/get)方法,你可以在这里了解更多信息。

Getter 方法

Go 语言不提供自动支持 getter 和 setter 方法。自己提供 getter 和 setter 方法没有问题,而且通常是合适的,但在 getter 的名称中加入 Get 既不符合惯例,也不是必需的。如果你有一个名为 owner 的字段(小写,未导出),getter 方法应该被命名为 Owner(大写,导出),而不是 GetOwner。使用大写名称导出字段提供了区分字段和方法的方法。如果需要的话,setter 函数可能被命名为 SetOwner。这两个名称在实践中都很好读:

owner := obj.Owner()
if owner != user {
    obj.SetOwner(user)
}
英文:

As already stated, the fields need to be exported to be accessible from another package. See the spec

> Exported identifiers
>
> An identifier may be exported to permit access to it from another
> package. An identifier is exported if both:
>
> - the first character of the identifier's name is a Unicode upper case
> letter (Unicode class "Lu");
> - and the identifier is declared in the
> package block or it is a field name or method name. All other
> identifiers are not exported.

If you want to keep the fields private, you need to use accessor (set/get) methods which you can read about here

> Getters
>
> Go doesn't provide automatic support for getters and setters. There's
> nothing wrong with providing getters and setters yourself, and it's
> often appropriate to do so, but it's neither idiomatic nor necessary
> to put Get into the getter's name. If you have a field called owner
> (lower case, unexported), the getter method should be called Owner
> (upper case, exported), not GetOwner. The use of upper-case names for
> export provides the hook to discriminate the field from the method. A
> setter function, if needed, will likely be called SetOwner. Both names
> read well in practice:
>
> owner := obj.Owner()
> if owner != user {
> obj.SetOwner(user)
> }

答案2

得分: 2

如果结构体位于与main函数不同的包中,那么你无法从该main函数中访问结构体的私有字段。

这就是“private”的含义。

英文:

If the struct is in a different package than the main function, then you cannot access the struct's private fields from that main function.

That is what "private" means.

huangapple
  • 本文由 发表于 2015年4月16日 17:06:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/29670099.html
匿名

发表评论

匿名网友

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

确定