I have 3 classes, which have several operation steps implemented in different functions. For example,
func ExternalAPI1() error
func ExternalAPI2(s string)
func internalProcess1() error
func internalProcess2(s []string) error
func internalProcess3(d int) error
For the internalProcessx, they're internal functions which may not be invoked by other classes, but these functions do have identical signatures. Should I generate an interface for them with only ExternalAPI1 and ExternalAPI2 included? or should I include all these 5 functions in the interface?
An interface describes the methods required to perform a certain action. In your case, this is definitely the following:
type API interface {
ExternalAPI1() error
ExternalAPI2(s string)
}
However, do note that this does not limit the use of non-exported methods when using your struct (not class) directly from the same package.
If you want the compiler to enforce that all structs which implement the interface have the unexported methods too, the unexported methods can certainly be included in the interface.
reflect.Type is an example from the stdlib (see here, godoc notes that the interface contains unexported methods)
tl;dr: don't worry about interfaces when creating structs, worry about interfaces when creating functions that would consume them.
The question overlooks an important underlying question: do you need an interface at all? I.e., is something going to accept values of the interface type, and operate on them without knowledge of the underlying type? If so, what methods will it call on the value? Those are the methods that should be in the interface.
Remember that Go uses duck interfaces; therefor, interfaces should be defined to suit the consumer, not the implementation. In fact, they should generally be defined alongside the consumer, not the implementation, because the implementation doesn't need to know anything about the interfaces it implements.
In Go, when a function or method can operate on "anything that implements method X", then alongside that function or method, you can define an "Xer" interface with that method signature. This allows anything to be passed to that function which meets the interface, and the function doesn't need to worry about what the underlying type is.