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

преобразовать интерфейс {} напрямую в int в Golang, где интерфейс хранит число в виде строки

У меня есть интерфейс map[string]{} из-за декодирования в JSON; с обычными данными интерфейс в большинстве случаев может быть только числом, но в виде строки, например:

var a interface{}
a="3"

Затем все данные будут сохранены в структуре.

type someStruct struct {
   ID string
   Number1 int
   Number2 int
   Number3 int
   Number4 int
}

Поэтому мне нужно преобразовать интерфейс в int, но я не могу сделать это легко и эффективно, потому что только код будет https://play.golang.org/p/oktbvTUbk93, довольно раздражает, и код кажется нечитаемым, если принять во внимание тот факт, что я должен обрабатывать все возможные ошибки

Я хотел бы преобразовать его непосредственно в int, я искал решения, но любое из этих преобразований работает так, как я хочу https://play.golang.org/p/Dw67U6kZwHC

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

type dataIn struct {
   Code int         `json:"code"`
   ID   string      `json:"id"`
   Data interface{} `json:"data"`
}

И затем я обрабатываю данные в соответствии с кодом и идентификатором, и все они представляют собой разные структуры данных, поэтому я не могу напрямую обрабатывать их с помощью JSON.

30.03.2018

  • Используйте пустой идентификатор для использования значений. Например, _, _ = ok, err. 30.03.2018
  • Если проблемное пространство широкое, ваш код тоже будет широким. Здесь нет магии. Займитесь программированием. 30.03.2018
  • Пакет json может кодировать и декодировать числа как строки: play.golang.org/p/MdrfqQjXLkw . См. этот вопрос, чтобы узнать, как работать с несогласованными полями. 30.03.2018
  • @peterSO Если я это сделаю, это будет по-прежнему неэффективно, потому что будет одно присвоение переменной, и тогда я смогу сохранить его в предназначении. 30.03.2018
  • @Peter Если вам интересно, почему я не просто декодирую его в структуру напрямую, это потому, что это динамические данные 30.03.2018
  • @Volker может быть, но я искал мнения для оптимального решения 30.03.2018

Ответы:


1

Похоже, вам нужен пользовательский метод unmarshal json в вашей основной структуре. Сначала выполните демаршалирование в основную структуру, чтобы получить свой код и идентификатор, затем используйте их в операторе switch, чтобы определить, какую структуру использовать для остальных данных, и демаршалируйте ее, перемешав эту структуру в поле данных.

30.03.2018
  • Для этого сценария мне пришлось бы разматывать дважды, я думаю, что это невозможно, не могли бы вы добавить пример, пожалуйста 30.03.2018
  • golang.org/pkg/encoding/json/#RawMessage — хороший пример именно такое поведение (посмотрите пример декодирования) 30.03.2018
  • Кроме того, именно об этом я говорил при использовании пользовательского метода немаршалирования: play.golang. org/p/ZyKhnXQ-nFB 30.03.2018
  • Я не знал, что смогу это сделать, и этот пользовательский маршал, кажется, то, что мне нужно, потому что использование rawMessage сделало бы мой код больше, спасибо! 30.03.2018

  • 2

    Создайте вспомогательную функцию, которая выполняет синтаксический анализ и проверку для вас, в одном месте:

    func parseInt(i interface{}) (int, error) {
        s, ok := i.(string)
        if !ok {
            return 0, errors.New("not string")
        }
        return strconv.Atoi(s)
    }
    

    И вы можете использовать это там, где это необходимо. Вот полный пример, в котором я также использовал другую вспомогательную функцию, которая занимается обработкой ошибок:

    m := map[string]interface{}{
        "number1": "1",
        "number2": "2",
        "number3": "3",
        "number4": "4",
        "ID":      "asdsa",
        "Title":   "asdas",
    }
    
    getInt := func(key string) int {
        n, err := parseInt(m[key])
        if err != nil {
            panic(err) // Decide what you wanna do with error
        }
        return n
    }
    
    // converting to struct
    data := element{
        ID:      m["ID"].(string),
        Title:   m["Title"].(string),
        Number1: getInt("number1"),
        Number2: getInt("number2"),
        Number3: getInt("number3"),
        Number4: getInt("number4"),
    }
    
    fmt.Printf("%+v\n", data)
    

    Результат приведенного выше (попробуйте на Go Playground):

    {ID:asdsa Title:asdas Number1:1 Number2:2 Number3:3 Number4:4}
    

    Также обратите внимание, что пакет с открытым исходным кодом github.com/icza/dyno должен помочь вам легко обрабатывать динамические объекты. (Раскрытие: я автор.) Например, у него есть функция dyno.GetInteger(), которая способна извлекать значение int64 из нескольких типов (таких как целые числа, числа с плавающей запятой, строки и т. д.).

    30.03.2018
  • ваше решение было довольно простым по сравнению с тем, что я пытался сделать, кстати. Хотя это решает фактический вопрос, есть решение, чтобы не нужно было ничего конвертировать в первую очередь 30.03.2018

  • 3

    Я до сих пор не понял ту часть, где вы заявили, что структура создается динамически. В любом случае, вы можете подключить метод struct, который выполняет преобразование int. Если поле Data типа interface{} всегда будет содержать целые числа, попробуйте следующее:

    type DataIn struct {
      Code int         `json:"code"`
      ID   string      `json:"id"`
      Data interface{} `json:"data"`
    }
    
    func (s DataIn) toInt() int {
       switch t := s.Data.(type)
       case int:
         i, _ := strings.Atoi(fmt.Sprintf("%v",s.Data))
         return i
    }
    
    // using it
    sampleData := someStruct{
      Number1: datain.toInt(),
    }
    
    30.03.2018
  • DataInt не хранит числа, он содержит map[string]interfarce{}, где внутри интерфейса числа в виде строк 30.03.2018
  • Новые материалы

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

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

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

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

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

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

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