6

假设我的项目具有以下层次结构:

fragment/fragment.go
main.go

fragment.go我有以下代码,有一个getter,没有setter:

package fragment

type Fragment struct {
    number int64   // private variable - lower case
}

func (f *Fragment) GetNumber() *int64 {
    return &f.number
}

在 main.go 中,我创建了一个Fragment并尝试在Fragment.number没有设置器的情况下进行更改:

package main

import (
    "fmt"
    "myproject/fragment"
)

func main() {
    f := new(fragment.Fragment)

    fmt.Println(*f.GetNumber()) // prints 0

    //f.number = 8 // error - number is private

    p := f.GetNumber()
    *p = 4                      // works. Now f.number is 4
    fmt.Println(*f.GetNumber()) // prints 4
}

所以通过使用指针,我改变了fragment包外的私有变量。我知道在例如 C 中,指针有助于避免复制大型结构/数组,并且它们应该使您能够更改它们指向的任何内容。但我不太明白它们应该如何处理私有变量。

所以我的问题是:

  1. 私有变量不应该保持私有,不管它们是如何访问的吗?
  2. How is this compared to other languages such as C++/Java? Is it the case there too, that private variables can be changed using pointers outside of the class?

My Background: I know a bit C/C++, rather fluent in Python and new to Go. I learn programming as a hobby so don't know much about technical things happening behind the scenes.

4

1 回答 1

8

You're not bypassing any access privilegies. If you acquire a *T from any imported package then you can always mutate *T, ie. the pointee at whole, as in an assignment. The imported package designer controls what you can get from the package, so the access control is not yours.

The restriction to what's said above is for structured types (structs), where the previous still holds, but the finer granularity of access control to a particular field is controlled by the field's name case even when referred to by a pointer to the whole structure. The field name must be uppercase to be visible outside its package.

Wrt C++: I believe you can achieve the same with one of the dozens C++ pointer types. Not sure which one, though.

Wrt Java: No, Java has no pointers. Not really comparable to pointers in Go (C, C++, ...).

于 2013-05-20T19:58:34.203 回答