Nano Hash - криптовалюты, майнинг, программирование

Пользовательский UnmarshalJSON не вызывается

У меня есть интерфейс, реализованный несколькими структурами. В одном из моих методов я создаю базу структуры на основе заданной строки, а затем анализирую json в определенной структуре. Для этого я реализовал UnmarshalJSON, но он никогда не вызывается.

Интерфейс:

type vehicle interface {
    vehicleType() string
    numberOfWheels() int
    EngineType() string
}

Две структуры, реализующие интерфейс:

type truck struct {
    loadCapacity  int
    capacityUnits string
}

func (t truck) vehicleType() string {
    return "Truck"
}

func (t truck) numberOfWheels() int {
    return 6
}

func (t truck) EngineType() string {
    return "Gasoline"
}

func (t *truck) UnmarshalJSON(data []byte) error {
    fmt.Println("Here in custom unmarshal")
    return nil
}

// -------------------------------------------
type ev struct {
    capacityInKWh int
}

func (e ev) vehicleType() string {
    return "Electric Vehicle"
}

func (e ev) numberOfWheels() int {
    return 4
}

func (e ev) EngineType() string {
    return "Electric"
}

func (e ev) Capacity() int {
    return e.capacityInKWh
}

Обратите внимание, что моя структура truck также реализует пользовательский UnmarshalJSON.

Теперь, в основном, я пытаюсь сделать следующее:

func main() {
    jsonData := []byte(`{"loadCapacity": 1000, "capacityUnits": "lb"}`)
    vehicleType := "truck"

    processVehicle(vehicleType, jsonData)
}

func processVehicle(vehicleType string, data []byte) {
    var myVehicle vehicle

    fmt.Println("Processing vehicle...")

    switch vehicleType {
    case "truck":
        myVehicle = truck{}
    }

    err := json.Unmarshal(data, &myVehicle)
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    fmt.Println(myVehicle)
}

Но я получаю следующую ошибку:

json: невозможно преобразовать объект в значение Go типа main.vehicle

Я знаю, что в реализованном UnmarshalJSON для truck нет фактического тела, но я ожидаю, что по крайней мере сообщение будет напечатано.

Что я делаю не так?


  • Таким образом, truck реализует интерфейс json.Unmarshaler, но вы выполняете демаршалинг в тип vehicle, который является просто интерфейсом, так что это не работает. Вам нужно развернуть в конкретное значение truck. 27.11.2020
  • @Flimzy, но я не знаю, какой тип транспортного средства получит processVehicle. Есть ли способ обойти это? Я имею в виду, я не хочу реализовывать несколько switch повсюду 27.11.2020
  • Затем все, что заключает в себе vehicle, должно принять решение о том, в какой тип неупорядочиваться. 27.11.2020
  • Вам нужен какой-то оператор switch (или эквивалентная логика) где-то. В Го нет никакой магии. 27.11.2020
  • В этом видео я рассказываю об использовании объекта-контейнера в аналогичной ситуации, которая @JimB, кажется, ускользнул от этого. 27.11.2020

Ответы:


1

Функция JSONUnmarshal находится на приемнике указателя. Используйте значение указателя для доступа к этому методу.

switch vehicleType {
case "truck":
    myVehicle = &truck{}  // <-- add & here
}

err := json.Unmarshal(data, myVehicle) // <-- & not needed here

Запустите на Go Playground.

27.11.2020
  • Это не имеет отношения к проблеме, поставленной вопросом. 27.11.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..