Я определил интерфейс Logger с помощью следующих методов:

type Logger interface {
    Info(args ...interface{})
    Warn(args ...interface{})
    Error(args ...interface{})
}

Теперь я хотел бы расширить тип log.Logger, чтобы он соответствовал этому интерфейсу. Поскольку log.Logger не определил эти методы, мне нужно было бы их реализовать.

Я попытался расширить его, добавив новые методы:

type LoggerImpl log.Logger

func (logger *LoggerImpl) Info(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Warn(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Println(v)
}

Но похоже, что это неправильный подход, поскольку я получаю сообщение об ошибке logger.Println undefined (type *LoggerImpl has no field or method Println).

Еще одно решение, которое я пробовал, - это встраивание типа, но оно также возвращает ошибку:

type LoggerImpl struct {
    log.Logger
}

func (logger *LoggerImpl) Info(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Warn(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Println(v)
}

func initLogger() *LoggerImpl {
    logger := log.New(os.Stdout, "", log.Lshortfile)

    return logger
}

Я получаю здесь ошибку при возврате регистратора из функции initLogger: cannot use logger (variable of type *log.Logger) as *LoggerImpl value in return statement

Как я могу изменить тип log.Logger в соответствии с интерфейсом Logger?

go
-1
Peter Parada 7 Сен 2020 в 07:56

1 ответ

Лучший ответ

Вы не можете определять методы для типа, объявленного в другом пакете. Однако вы можете определить новый тип, встроить старый тип в новый тип и определить новые методы для нового типа:

type LoggerImpl struct {
   *log.Logger
}


func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Logger.Println(v)
}

func initLogger() *LoggerImpl {
    logger := &LoggerImpl{Logger:log.New(os.Stdout, "", log.Lshortfile)}

    return logger
}
...

Выше LoggerImpl содержит все методы, объявленные для log.Logger, и методы, которые вы явно объявили в этом пакете.

В общем: если вы встраиваете тип в другую структуру, включающая структура получает все методы, определенные для встроенного типа. Если вы определяете новый тип из другого типа, новый тип не получает ни одного из методов базового типа.

3
Burak Serdar 7 Сен 2020 в 05:38