Не может определять новые методы для моделей нелокального типа

Я хочу поместить все свои модели в общую Common библиотеку.

Итак, я сделал новое репо: gitlab.com/xxx/common

Внутрь я положил пакет: models

Вот определение объекта:

type Meter struct {
    ID           string
    OperationID  string
    Type         ConsoProd
    Unit         string
    Timestep     time.Duration
    Measures     []Measure 
    FetchMethod  AcquisitionMethod
    Metadata     interface{}
}

Теперь я хочу использовать его во внешнем проекте, я делаю:

go get gitlab.com/xxx/common

И Go Modules загрузит его.

Я импортирую его так:

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
}

Но Goland его не решит, и при компиляции получаю:

cannot define new methods on non-local type models.Meter

Почему это происходит и что я могу сделать, чтобы это исправить?

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
3
0
2 788
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не разрешается определять методы вне пакета, в котором определен тип. Это оставляет вам несколько вариантов:

  1. Определите методы в пакете models. Это самый простой подход при работе с вашим собственным кодом, но, конечно, он не будет работать для сторонних типов.

  2. Создайте обычную функцию вместо метода (func String(meter models.Meter) string). Это может быть менее идиоматично (особенно для метода String), а также не имеет доступа к закрытым полям (если только вы не определите функцию в пакете models, и в этом случае вы можете просто определить вместо этого метод).

  3. Создайте новый тип, встраивающий исходный тип. Это было бы немного громоздко в использовании, но позволяет расширить существующее поведение. Что-то вроде этого:

`

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"
}

Ok ! Вариант первый имеет смысл! Спасибо за вашу помощь

Juliatzin 19.07.2019 15:09

Простой,

import ...bla/bla/Meter

type extended Meter

Ссылка: https://github.com/golang/go/issues/31631#issuecomment-486075295

Другие вопросы по теме