Methods can be defined on any file in the package, but my recommendation is to organize the code as shown below:
- Define constants
- Define vars
- Define interface
- Define struct
- Implementation of methods on struct
Example:
package models
// list of packages to import
import (
"fmt"
)
// list of constants
const (
ConstExample = "const before vars"
)
// list of variables
var (
ExportedVar = 42
nonExportedVar = "so say we all"
)
type Fly interface {
Fly() string
}
// Main type(s) for the file,
// try to keep the lowest amount of structs per file when possible.
type Duck struct {
Name string
Breed *BirdBreed
}
type BirdBreed struct {
Name string
BiologicalName string
}
// List of functions
func NewDuck(name string) *Duck {
return &Duck{Name: name,
Breed: &BirdBreed{
Name: "Red head",
BiologicalName: "some crazy name",
},
}
}
// List of methods
func (d *Duck) Fly() string {
return fmt.Sprintf("I can fly: %s %s", d.FirstName, d.Breed.Name)
}