1

I have a struct Direction with a value of type string. Direction should be N, S, W or E.

type Direction struct {
    value string
}

Inspired by an answer of this question: Does Go have "if x in" construct similar to Python? I guess a good way to create Direction in a valid manner can be this one:

func NewDirection(direction string) Direction {
    switch direction {
        case "N","S","W","E": return Direction{direction}
    }
    panic("invalid direction")
}

But this is not enough for me because I can still create invalid Direction:

d := Direction{"X"}

I also found this interesting article about enforcing the use of constructor in go. Reading this article I can see that is necessary the usage of another package. May I have a "protected" struct in, for example, main package?

sensorario
  • 20,262
  • 30
  • 97
  • 159

1 Answers1

3

You've already done almost everything you should do by convention:

  • make the field unexported
  • provide a constructor
  • put a comment on the type stating that the constructor should be used, and explain how zero-values are treated (if that matters)

Now users of the package can't modify the field, and the existence of the constrictor makes it clear that it should be called to create valid instances. This is the convention that is set by the standard library.

Sure, there are other ways that you can make it even harder to invalidate values but this is essentially just wasting time and overcomplicating your code for the sake of an unwinnable arms race against an imaginary opponent.

If someone doesn't understand the language and doesn't read documentation, then they're always going to find a way to misuse it. If they are actively trying to sabotage themselves, there's nothing you can do to stop them and no reason to either.

Packages are the smallest functional unit of code organization in Go. There is no way to protect field at, for example, the file level. Even files within the same package effectively operate as if all their code was in the same file. Therefore, any code in the same package as the constructor will have the same privileges as the constructor.

Hymns For Disco
  • 7,530
  • 2
  • 17
  • 33