Заставить маршара провалиться из строки - PullRequest
0 голосов
/ 06 сентября 2018

Возможно ли сделать сбой маршала внутри функции getJSONStr после получения некоторой строки?

package main

import (
   "fmt"
   "encoding/json"
)

type obj struct {
  Name string            `json:"name"`
}

func getJSONStr(s string) (*string, error) {
 t := new(obj)
 t.Name = s
 b, err := json.Marshal(t)
 if err != nil {
    return nil, err
 }
 str := string(b)
 return &str, nil
}

func main() {
   str, err := getJSONStr("VALIDATE")
   fmt.Println("str",*str)
   fmt.Println("err",err)
}

Я пытался сделать это, но безуспешно.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Вы можете реализовать json.Marshaler для obj или для определенного поля внутри obj. Этот маршалер может проверить значение поля и вернуть ошибку. Вот пример с пользовательским маршалером, добавленным для поля Name, которое завершается ошибкой, если Name равно "Boom!"

type NameWithValidation string

func (s NameWithValidation) MarshalJSON() ([]byte, error) {
    if string(s) == "Boom!" {
        return nil, fmt.Errorf("Name '%s' failed validation", s)
    }
    return json.Marshal(string(s))
}

type obj struct {
    Name NameWithValidation `json:"name"`
}

При маршалинге json.Marshal() проверяет, реализует ли тип json.Marshaler и, если это так, он вызывает MarshalJSON() вместо того, чтобы пытаться маршалировать сам элемент.

0 голосов
/ 06 сентября 2018

Из Годоков

Канальные, комплексные и функциональные значения не могут быть закодированы в JSON. Попытка закодировать такое значение заставляет Marshal вернуть UnsupportedTypeError.

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

...