417 lines
22 KiB
Plaintext
Generated
417 lines
22 KiB
Plaintext
Generated
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Go by Example: 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 by Example</a>: JSON</h2>
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Go offers built-in support for JSON encoding and
|
|
decoding, including to and from built-in and custom
|
|
data types.</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/JOQpRGJWAxR"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
|
|
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><span class="kn">import</span> <span class="p">(</span>
|
|
<span class="s">"encoding/json"</span>
|
|
<span class="s">"fmt"</span>
|
|
<span class="s">"os"</span>
|
|
<span class="p">)</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>We’ll use these two structs to demonstrate encoding and
|
|
decoding of custom types below.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Only exported fields will be encoded/decoded in JSON.
|
|
Fields must start with capital letters to be exported.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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:"page"`</span>
|
|
<span class="nx">Fruits</span> <span class="p">[]</span><span class="kt">string</span> <span class="s">`json:"fruits"`</span>
|
|
<span class="p">}</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>First we’ll look at encoding basic data types to
|
|
JSON strings. Here are some examples for atomic
|
|
values.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"> <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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"> <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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"> <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="nf">Marshal</span><span class="p">(</span><span class="s">"gopher"</span><span class="p">)</span>
|
|
<span class="nx">fmt</span><span class="p">.</span><span class="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>And here are some for slices and maps, which encode
|
|
to JSON arrays and objects as you’d expect.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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">"apple"</span><span class="p">,</span> <span class="s">"peach"</span><span class="p">,</span> <span class="s">"pear"</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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"> <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">"apple"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"lettuce"</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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>The JSON package can automatically encode your
|
|
custom data types. It will only include exported
|
|
fields in the encoded output and will by default
|
|
use those names as the JSON keys.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">res1D</span> <span class="o">:=</span> <span class="o">&</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">"apple"</span><span class="p">,</span> <span class="s">"peach"</span><span class="p">,</span> <span class="s">"pear"</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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>You can use tags on struct field declarations
|
|
to customize the encoded JSON key names. Check the
|
|
definition of <code>response2</code> above to see an example
|
|
of such tags.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">res2D</span> <span class="o">:=</span> <span class="o">&</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">"apple"</span><span class="p">,</span> <span class="s">"peach"</span><span class="p">,</span> <span class="s">"pear"</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="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Now let’s look at decoding JSON data into Go
|
|
values. Here’s an example for a generic data
|
|
structure.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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">`{"num":6.13,"strs":["a","b"]}`</span><span class="p">)</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>We need to provide a variable where the JSON
|
|
package can put the decoded data. This
|
|
<code>map[string]interface{}</code> will hold a map of strings
|
|
to arbitrary data types.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Here’s the actual decoding, and a check for
|
|
associated errors.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<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="nf">Unmarshal</span><span class="p">(</span><span class="nx">byt</span><span class="p">,</span> <span class="o">&</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="nf">Println</span><span class="p">(</span><span class="nx">dat</span><span class="p">)</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>In order to use the values in the decoded map,
|
|
we’ll need to convert them to their appropriate type.
|
|
For example here we convert the value in <code>num</code> to
|
|
the expected <code>float64</code> type.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">num</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">"num"</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="nf">Println</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Accessing nested data requires a series of
|
|
conversions.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">strs</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">"strs"</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="nf">Println</span><span class="p">(</span><span class="nx">str1</span><span class="p">)</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>We can also decode JSON into custom data types.
|
|
This has the advantages of adding additional
|
|
type-safety to our programs and eliminating the
|
|
need for type assertions when accessing the decoded
|
|
data.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">str</span> <span class="o">:=</span> <span class="s">`{"page": 1, "fruits": ["apple", "peach"]}`</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="nf">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">&</span><span class="nx">res</span><span class="p">)</span>
|
|
<span class="nx">fmt</span><span class="p">.</span><span class="nf">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="nf">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>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>In the examples above we always used bytes and
|
|
strings as intermediates between the data and
|
|
JSON representation on standard out. We can also
|
|
stream JSON encodings directly to <code>os.Writer</code>s like
|
|
<code>os.Stdout</code> or even HTTP response bodies.</p>
|
|
|
|
</td>
|
|
<td class="code">
|
|
|
|
<pre class="chroma">
|
|
<span class="nx">enc</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nf">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">"apple"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"lettuce"</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="nf">Encode</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><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">"gopher"
|
|
</span><span class="go">["apple","peach","pear"]
|
|
</span><span class="go">{"apple":5,"lettuce":7}
|
|
</span><span class="go">{"Page":1,"Fruits":["apple","peach","pear"]}
|
|
</span><span class="go">{"page":1,"fruits":["apple","peach","pear"]}
|
|
</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">{"apple":5,"lettuce":7}</span></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>We’ve covered the basic of JSON in Go here, but check
|
|
out the <a href="http://blog.golang.org/2011/01/json-and-go.html">JSON and Go</a>
|
|
blog post and <a href="http://golang.org/pkg/encoding/json/">JSON package docs</a>
|
|
for more.</p>
|
|
|
|
</td>
|
|
<td class="code empty">
|
|
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
|
|
<p class="next">
|
|
Next example: <a href="xml">XML</a>.
|
|
</p>
|
|
|
|
|
|
<p class="footer">
|
|
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> and <a href="https://eli.thegreenplace.net">Eli Bendersky</a> | <a href="https://github.com/mmcgrana/gobyexample">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, _ :\u003D json.Marshal(true)\u000A fmt.Println(string(bolB))\u000A');codeLines.push(' intB, _ :\u003D json.Marshal(1)\u000A fmt.Println(string(intB))\u000A');codeLines.push(' fltB, _ :\u003D json.Marshal(2.34)\u000A fmt.Println(string(fltB))\u000A');codeLines.push(' strB, _ :\u003D json.Marshal(\"gopher\")\u000A fmt.Println(string(strB))\u000A');codeLines.push(' slcD :\u003D []string{\"apple\", \"peach\", \"pear\"}\u000A slcB, _ :\u003D json.Marshal(slcD)\u000A fmt.Println(string(slcB))\u000A');codeLines.push(' mapD :\u003D map[string]int{\"apple\": 5, \"lettuce\": 7}\u000A mapB, _ :\u003D json.Marshal(mapD)\u000A fmt.Println(string(mapB))\u000A');codeLines.push(' res1D :\u003D \u0026response1{\u000A Page: 1,\u000A Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A res1B, _ :\u003D json.Marshal(res1D)\u000A fmt.Println(string(res1B))\u000A');codeLines.push(' res2D :\u003D \u0026response2{\u000A Page: 1,\u000A Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A res2B, _ :\u003D json.Marshal(res2D)\u000A fmt.Println(string(res2B))\u000A');codeLines.push(' byt :\u003D []byte(`{\"num\":6.13,\"strs\":[\"a\",\"b\"]}`)\u000A');codeLines.push(' var dat map[string]interface{}\u000A');codeLines.push(' if err :\u003D json.Unmarshal(byt, \u0026dat); err !\u003D nil {\u000A panic(err)\u000A }\u000A fmt.Println(dat)\u000A');codeLines.push(' num :\u003D dat[\"num\"].(float64)\u000A fmt.Println(num)\u000A');codeLines.push(' strs :\u003D dat[\"strs\"].([]interface{})\u000A str1 :\u003D strs[0].(string)\u000A fmt.Println(str1)\u000A');codeLines.push(' str :\u003D `{\"page\": 1, \"fruits\": [\"apple\", \"peach\"]}`\u000A res :\u003D response2{}\u000A json.Unmarshal([]byte(str), \u0026res)\u000A fmt.Println(res)\u000A fmt.Println(res.Fruits[0])\u000A');codeLines.push(' enc :\u003D json.NewEncoder(os.Stdout)\u000A d :\u003D 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>
|