Как преобразовать символы новой строки в правильный JSON в GO?

У меня есть строки, которые я хотел бы преобразовать в JSON. Здесь используется кодировка / json, другие пакеты не пробовал.

Строки могут содержать символы новой строки и другие вещи, которые нарушают JSON, если они сохранены как есть.

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

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

Пример кода:

package main

import (
    "fmt"
    "encoding/json"
)

func main() {
    type Test struct {
        Input string
    }
    regularString := Test{"asd\nqwe"}
    out, err := json.Marshal(regularString)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(out))

    literalString := Test{`asd\nqwe`}
    out, err = json.Marshal(literalString )
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(out))
}

person LauriK    schedule 14.11.2018    source источник
comment
Какой результат вы ожидаете от своего образца? Если это проясняет, я добавил пару дополнительных Println, которые показывают строки, кодируемые на игровой площадке go здесь. Обратите внимание, что в первом есть настоящая новая строка, а во втором - \ n, который будет закодирован как \\ n в json, чтобы предотвратить его интерпретацию как новую строку.   -  person Hugh    schedule 14.11.2018


Ответы (1)


encoding/json правильно кодирует все строковые значения.

Ваш первый пример работает так, как вы ожидаете, потому что вы используете интерпретируемый строковый литерал, и если он содержит последовательность \n, компилятор заменит ее символом новой строки.

Ваш второй пример работает не так, как вы ожидаете, потому что вы использовали необработанный строковый литерал, который, если он содержит последовательность \n, не будет заменен, но эти 2 символа останутся в строке. И это будет правильно экранировано encoding/json, чтобы оно оставалось в выводе JSON.

Так что в основном

"asd\nqwe"`

а также

`asd\nqwe`

- это две разные строки, они не равны, поэтому их экранированные значения JSON также разные.

Дополнительные сведения см. В Spec: String literals.

Обратите внимание: если вы хотите создать строковое значение с использованием необработанного строкового литерала, вы не можете использовать в нем escape-последовательности. Чтобы добавить новую строку в необработанный строковый литерал, просто разорвите строку, например:

s := `asd
qwe`

Другой вариант - «разбить» строковый литерал и вставить новую строку, используя интерпретируемый строковый литерал (и объединить части):

s := `asd` + "\n" + `qwe`
person icza    schedule 14.11.2018
comment
Да, в этом есть смысл, но как мне заставить его работать? - person LauriK; 14.11.2018
comment
@LauriK: Что не работает? Вы продемонстрировали, что это работает с ". - person Flimzy; 14.11.2018
comment
@LauriK Да, это работает. Если вы хотите, чтобы строка содержала новую строку, используйте строковое значение, которое содержит новую строку, а не обратную косую черту, за которой следует символ n. - person icza; 14.11.2018
comment
@LauriK Добавлены примеры того, как вы можете включить новую строку в необработанный строковый литерал. - person icza; 14.11.2018