I want to put all my models in a shared Common
lib.
So, I made a new repo: gitlab.com/xxx/common
Inside I put a package: models
Here is the definition of an object:
type Meter struct {
ID string
OperationID string
Type ConsoProd
Unit string
Timestep time.Duration
Measures []Measure
FetchMethod AcquisitionMethod
Metadata interface{}
}
Now, I want to use it in an external project, I do:
go get gitlab.com/xxx/common
And Go Modules will download it.
I import use it like that:
import "gitlab.com/xxx/common/models"
//String transparent method
func (meter models.Meter) String() string {
var stringifyMeter string
stringifyMeter += "Meter " + meter.ID + " is a " + meter.Type.String() + " and compute in operation #" + meter.OperationID + "."
return stringifyMeter
}
But Goland will not resolve it, and when I compile, I get:
cannot define new methods on non-local type models.Meter
Why is it happening and what can I do to fix it ?
It is not allowed to define methods outside the package where the type is defined. This leaves you with a couple of options:
Define the methods in the models
package. That's the simplest approach when dealing with your own code but of course won't work for 3rd-party types.
Create a regular function instead of a method (func String(meter models.Meter) string
). That might be less idiomatic, though (especially for the String
method), and also does not have access to private fields (unless you define the function in the models
package, in which case you could just define the method instead).
Create a new type embedding the original type. That would be a bit cumbersome to use but allows you to extend existing behavior. Something like this:
`
package main
import (
"fmt"
"time"
)
func main() {
myTime := MyTime{time.Now()}
fmt.Println(myTime) /* behaves as time.Time */
fmt.Println(myTime.Foo()) /* also has extra methods */
}
type MyTime struct {
time.Time
}
func (m MyTime) Foo() string {
return "foo"
}