2019-10-14 11:38:21 +03:00

425 lines
24 KiB
Plaintext
Generated
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go в примерах: JSON</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'regular-expressions';
}
if (e.key == "ArrowRight") {
window.location.href = 'xml';
}
}
</script>
<body>
<div class="example" id="json">
<h2><a href="./">Go в примерах</a>: JSON</h2>
<table>
<tr>
<td class="docs">
<p>Go предлагает встроенную поддержку кодирования и
декодирования JSON, в том числе встроенных и
пользовательских типов данных.</p>
</td>
<td class="code empty leading">
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<a href="http://play.golang.org/p/Lky4Hyyl2-t" target="_blank"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;encoding/json&quot;</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;os&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Мы будем использовать эти две структуры, для демонстрации
кодирования и декодирования.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">type</span> <span class="nx">response1</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">Page</span> <span class="kt">int</span>
<span class="nx">Fruits</span> <span class="p">[]</span><span class="kt">string</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Только экспортируемые поля могут быть кодированы и
декодированы в JSON. Поля должны начинаться с
заглавной буквы.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">type</span> <span class="nx">response2</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">Page</span> <span class="kt">int</span> <span class="s">`json:&quot;page&quot;`</span>
<span class="nx">Fruits</span> <span class="p">[]</span><span class="kt">string</span> <span class="s">`json:&quot;fruits&quot;`</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Для начала мы рассмотрим кодирование данных в
JSON строку. Вот несколько примеров для простых
типов данных.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">bolB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">bolB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">intB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">intB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">fltB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="mf">2.34</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">fltB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">strB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="s">&quot;gopher&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">strB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>А вот примеры для срезов и карт, которые кодируются
в JSON массивы и объекты, как мы и ожидаем.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">slcD</span> <span class="o">:=</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}</span>
<span class="nx">slcB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">slcD</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">slcB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">mapD</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&quot;lettuce&quot;</span><span class="p">:</span> <span class="mi">7</span><span class="p">}</span>
<span class="nx">mapB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">mapD</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">mapB</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Пакет JSON может автоматически кодировать ваши
пользовательские типы данных. Он будет включать
только экспортируемые поля в закодированный
вывод и по умолчанию будет использовать эти
имена в качестве ключей JSON.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">res1D</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">response1</span><span class="p">{</span>
<span class="nx">Page</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
<span class="nx">Fruits</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}}</span>
<span class="nx">res1B</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">res1D</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">res1B</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Вы можете использовать теги в объявлениях
структурных полей для настройки кодированных имен
ключей JSON. Проверьте определение <code>response2</code>
выше, чтобы увидеть пример таких тегов.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">res2D</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">response2</span><span class="p">{</span>
<span class="nx">Page</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
<span class="nx">Fruits</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}}</span>
<span class="nx">res2B</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">res2D</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">res2B</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Теперь давайте рассмотрим декодирование данных
JSON в значения Go. Вот пример для общей
структуры данных.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">byt</span> <span class="o">:=</span> <span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="s">`{&quot;num&quot;:6.13,&quot;strs&quot;:[&quot;a&quot;,&quot;b&quot;]}`</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Нам нужно предоставить переменную, в которую пакет
JSON может поместить декодированные данные.
`map[string]interface{} будет содержать карту
строк для произвольных типов данных.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">dat</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kd">interface</span><span class="p">{}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Вот фактическое декодирование и проверка на наличие
ошибок.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Unmarshal</span><span class="p">(</span><span class="nx">byt</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">dat</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">dat</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Чтобы использовать значения в декодированной карте,
нам нужно преобразовать их в соответствующий тип.
Например, здесь мы конвертируем значение из <code>num</code>
в ожидаемый тип <code>float64</code>.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">num</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">&quot;num&quot;</span><span class="p">].(</span><span class="kt">float64</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Доступ к вложенным данным требует ряда преобразований.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">strs</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">&quot;strs&quot;</span><span class="p">].([]</span><span class="kd">interface</span><span class="p">{})</span>
<span class="nx">str1</span> <span class="o">:=</span> <span class="nx">strs</span><span class="p">[</span><span class="mi">0</span><span class="p">].(</span><span class="kt">string</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">str1</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Мы также можем декодировать JSON в пользовательские
типы данных. Это дает преимущество добавления
дополнительной безопасности типов в наши программы
и устранения необходимости в определении типрв
при доступе к декодированным данным.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">str</span> <span class="o">:=</span> <span class="s">`{&quot;page&quot;: 1, &quot;fruits&quot;: [&quot;apple&quot;, &quot;peach&quot;]}`</span>
<span class="nx">res</span> <span class="o">:=</span> <span class="nx">response2</span><span class="p">{}</span>
<span class="nx">json</span><span class="p">.</span><span class="nx">Unmarshal</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="nx">str</span><span class="p">),</span> <span class="o">&amp;</span><span class="nx">res</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">res</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">Fruits</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>В приведенных выше примерах мы всегда использовали
байты и строки в качестве промежуточных звеньев между
данными и представлением JSON на стандартном выходе.
Мы также можем транслировать JSON-кодировки напрямую
в <code>os.Writer</code>, такие как <code>os.Stdout</code> или даже HTTP-тела
ответа.</p>
</td>
<td class="code">
<div class="highlight"><pre> <span class="nx">enc</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">NewEncoder</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">)</span>
<span class="nx">d</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&quot;lettuce&quot;</span><span class="p">:</span> <span class="mi">7</span><span class="p">}</span>
<span class="nx">enc</span><span class="p">.</span><span class="nx">Encode</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">$</span> go run json.go
<span class="go">true</span>
<span class="go">1</span>
<span class="go">2.34</span>
<span class="go">&quot;gopher&quot;</span>
<span class="go">[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]</span>
<span class="go">{&quot;apple&quot;:5,&quot;lettuce&quot;:7}</span>
<span class="go">{&quot;Page&quot;:1,&quot;Fruits&quot;:[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]}</span>
<span class="go">{&quot;page&quot;:1,&quot;fruits&quot;:[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]}</span>
<span class="go">map[num:6.13 strs:[a b]]</span>
<span class="go">6.13</span>
<span class="go">a</span>
<span class="go">{1 [apple peach]}</span>
<span class="go">apple</span>
<span class="go">{&quot;apple&quot;:5,&quot;lettuce&quot;:7}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Мы рассмотрели основы JSON в Go, но ознакомьтесь с
публикацией в блоге <a href="http://blog.golang.org/2011/01/json-and-go.html">JSON and Go</a>
и документацией по <a href="http://golang.org/pkg/encoding/json/">пакету JSON</a>.</p>
</td>
<td class="code empty">
</td>
</tr>
</table>
<p class="next">
Следующий пример: <a href="xml">XML</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/json">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"encoding/json\"\u000A \"fmt\"\u000A \"os\"\u000A)\u000A');codeLines.push('type response1 struct {\u000A Page int\u000A Fruits []string\u000A}\u000A');codeLines.push('type response2 struct {\u000A Page int `json:\"page\"`\u000A Fruits []string `json:\"fruits\"`\u000A}\u000A');codeLines.push('func main() {\u000A');codeLines.push(' bolB, _ := json.Marshal(true)\u000A fmt.Println(string(bolB))\u000A');codeLines.push(' intB, _ := json.Marshal(1)\u000A fmt.Println(string(intB))\u000A');codeLines.push(' fltB, _ := json.Marshal(2.34)\u000A fmt.Println(string(fltB))\u000A');codeLines.push(' strB, _ := json.Marshal(\"gopher\")\u000A fmt.Println(string(strB))\u000A');codeLines.push(' slcD := []string{\"apple\", \"peach\", \"pear\"}\u000A slcB, _ := json.Marshal(slcD)\u000A fmt.Println(string(slcB))\u000A');codeLines.push(' mapD := map[string]int{\"apple\": 5, \"lettuce\": 7}\u000A mapB, _ := json.Marshal(mapD)\u000A fmt.Println(string(mapB))\u000A');codeLines.push(' res1D := &response1{\u000A Page: 1,\u000A Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A res1B, _ := json.Marshal(res1D)\u000A fmt.Println(string(res1B))\u000A');codeLines.push(' res2D := &response2{\u000A Page: 1,\u000A Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A res2B, _ := json.Marshal(res2D)\u000A fmt.Println(string(res2B))\u000A');codeLines.push(' byt := []byte(`{\"num\":6.13,\"strs\":[\"a\",\"b\"]}`)\u000A');codeLines.push(' var dat map[string]interface{}\u000A');codeLines.push(' if err := json.Unmarshal(byt, &dat); err != nil {\u000A panic(err)\u000A }\u000A fmt.Println(dat)\u000A');codeLines.push(' num := dat[\"num\"].(float64)\u000A fmt.Println(num)\u000A');codeLines.push(' strs := dat[\"strs\"].([]interface{})\u000A str1 := strs[0].(string)\u000A fmt.Println(str1)\u000A');codeLines.push(' str := `{\"page\": 1, \"fruits\": [\"apple\", \"peach\"]}`\u000A res := response2{}\u000A json.Unmarshal([]byte(str), &res)\u000A fmt.Println(res)\u000A fmt.Println(res.Fruits[0])\u000A');codeLines.push(' enc := json.NewEncoder(os.Stdout)\u000A d := map[string]int{\"apple\": 5, \"lettuce\": 7}\u000A enc.Encode(d)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>