Information hiding within a package

344 views
Skip to first unread message

Orson Cart

unread,
Jan 21, 2020, 6:04:28 AM1/21/20
to golang-nuts

I'm still new to using Go so maybe I'm missing something of the 'culture' but I find that I'd often like to be able to hide implementation detail on a level that is more finely grained than the package.

I'm aware that using case it's possible to define for instance struct members that are not accessible to code outside of the struct's package.

I'm also aware that you can employ this concept such that a package can define a public interface which can be *used* by code outside of the package but which effectively can't be *implemented* by code outside the package. There's an example of this in section 2 here:

I guess I'm looking for something like opaque pointers which were employed to good effect in C to hide implementation details from 'peer' source files: https://en.wikipedia.org/wiki/Opaque_pointer#C

If as I suspect there is no way of achieving what I'm looking for, does anyone know of a good reason why this level of information hiding isn't possible in Go? Do experienced Go developers just not feel the need for it?

TIA
Orson


Axel Wagner

unread,
Jan 21, 2020, 7:24:19 AM1/21/20
to Orson Cart, golang-nuts
On Tue, Jan 21, 2020 at 12:04 PM Orson Cart <objectiv...@gmail.com> wrote:
I'm still new to using Go so maybe I'm missing something of the 'culture' but I find that I'd often like to be able to hide implementation detail on a level that is more finely grained than the package.
[…]
If as I suspect there is no way of achieving what I'm looking for, does anyone know of a good reason why this level of information hiding isn't possible in Go? Do experienced Go developers just not feel the need for it?

I don't really give much about the dichotomy of "experienced" Go developers vs. unexperienced ones, but I can say that I never felt the need. To the degree that I think it would be useful to turn this around: Why *do* you feel that need? What is the problem you are trying to solve, with just, say, using a rule that you are not touching other type's unexported fields or methods outside that type's methods?

You also mention C, but note that C doesn't allow anything like this (even less so than Go), if you think about it. It's just that in C, the unit of compilation is a file, not a package. So you don't actually *have* anything like "peer" source files. Every file is its own unit and if you want to interact with values, you need to tell the compiler how they look. But there is no actual access-restriction put on anything. Even if a package intends for something to be an opaque pointer, you can always just add a type-def for that type and still access all its fields. Go allows this too, of course, using unsafe. But the Go notion of a "package" of related source files with shared visibility just doesn't exist in C. You can restrict things to a single file (by declaring them static), but that's it. If it's not static, it can be used from *any* other file linked into the final binary in exactly the same way.

Axel Wagner

unread,
Jan 21, 2020, 7:34:17 AM1/21/20
to Orson Cart, golang-nuts
Come to think of it, that might actually just be the answer you are looking for: C and Go are the same, in terms of visibility rules they allow. Any identifier in the namespace is either unexported (static in C) and visible to exactly this compilation unit, or it's exported (not static, in C) and exposed to other compilation units. The only difference is that Go allows, for convenience, that compilation unit to be split into multiple files and calls it a package. So, coming from C, this is a very natural delineation to choose.

Brian Candler

unread,
Jan 21, 2020, 8:08:06 AM1/21/20
to golang-nuts
On Tuesday, 21 January 2020 11:04:28 UTC, Orson Cart wrote:
I guess I'm looking for something like opaque pointers which were employed to good effect in C to hide implementation details from 'peer' source files: https://en.wikipedia.org/wiki/Opaque_pointer#C


You can hide implementation details from peer source *packages*.  You probably want to break your code up into smaller packages anyway: see
especially the section under "Bad package names"

A package which contains an 'internal' subdirectory can contain other sub-packages which are not exported: this may also be useful to you.

Reply all
Reply to author
Forward
0 new messages