Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go Programming - bypassing access privileges using pointers

Tags:

pointers

go

Let's say I have the following hierarchy for my project:

fragment/fragment.go
main.go

And in the fragment.go I have the following code, with one getter and no setter:

package fragment

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

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

And in the main.go I create a Fragment and try to change Fragment.number without a setter:

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
}

So by using the pointer, I changed the private variable outside of the fragment package. I understand that in for example C, pointers help to avoid copying large struct/arrays and they are supposed to enable you to change whatever they're pointing to. But I don't quite understand how they are supposed to work with private variables.

So my questions are:

  1. Shouldn't the private variables stay private, no matter how they are accessed?
  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.

like image 643
user31208 Avatar asked May 20 '13 19:05

user31208


People also ask

Can you use pointers in Go?

Go has pointers. A pointer holds the memory address of a value. The data is stored in the memory when the program runs and each has a number- the memory address, which can be assigned to a pointer, and through which we can find the data stored in memory.

How do I dereference a pointer in Go?

Pointers can be dereferenced by adding an asterisk * before a pointer.

What is unsafe pointer in Go?

Go unsafe pointers mean the types whose underlying types are unsafe. Pointer . The zero values of unsafe pointers are also represented with the predeclared identifier nil . Before Go 1.17, the unsafe standard package has already provided three functions.

Do you need to use pointers in Go?

If you don't need a pointer, you should stick to a value. However, in many cases, you will indeed need a pointer. The problem is, Golang being Golang, you are passing by value, meaning you are not passing the real p but only a clone that copies it's values.


1 Answers

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++, ...).

like image 172
zzzz Avatar answered Oct 02 '22 10:10

zzzz