2019-10-15 15:02:01 +03:00

223 lines
9.8 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 в примерах: Defer</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'panic';
}
if (e.key == "ArrowRight") {
window.location.href = 'collection-functions';
}
}
</script>
<body>
<div class="example" id="defer">
<h2><a href="./">Go в примерах</a>: Defer</h2>
<table>
<tr>
<td class="docs">
<p><em>Defer</em> используется, чтобы гарантировать, что
вызов функции будет выполнен позже при выполнении
программы, обычно для целей очистки. <code>defer</code> часто
используется там, где в других языках используются
<code>ensure</code> и <code>finally</code>.</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/lVhFAPGaGby" 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;fmt&quot;</span>
<span class="s">&quot;os&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Предположим, мы хотим создать файл, записать в него,
а затем закрыть, когда закончим. Вот как нам поможет
<code>defer</code>.</p>
</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>Сразу же после получения объекта файла с помощью
<code>createFile</code> мы откладываем закрытие этого файла
с помощью <code>closeFile</code>. Она будет выполнена в
конце включающей функции (<code>main</code>) после завершения
<code>writeFile</code>.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">f</span> <span class="o">:=</span> <span class="nx">createFile</span><span class="p">(</span><span class="s">&quot;/tmp/defer.txt&quot;</span><span class="p">)</span>
<span class="k">defer</span> <span class="nx">closeFile</span><span class="p">(</span><span class="nx">f</span><span class="p">)</span>
<span class="nx">writeFile</span><span class="p">(</span><span class="nx">f</span><span class="p">)</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">createFile</span><span class="p">(</span><span class="nx">p</span> <span class="kt">string</span><span class="p">)</span> <span class="o">*</span><span class="nx">os</span><span class="p">.</span><span class="nx">File</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="s">&quot;creating&quot;</span><span class="p">)</span>
<span class="nx">f</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nx">Create</span><span class="p">(</span><span class="nx">p</span><span class="p">)</span>
<span class="k">if</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="k">return</span> <span class="nx">f</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">writeFile</span><span class="p">(</span><span class="nx">f</span> <span class="o">*</span><span class="nx">os</span><span class="p">.</span><span class="nx">File</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="s">&quot;writing&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Fprintln</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="s">&quot;data&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="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Важно проверять наличие ошибок при закрытии файла,
даже в отложенной функции.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">func</span> <span class="nx">closeFile</span><span class="p">(</span><span class="nx">f</span> <span class="o">*</span><span class="nx">os</span><span class="p">.</span><span class="nx">File</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="s">&quot;closing&quot;</span><span class="p">)</span>
<span class="nx">err</span> <span class="o">:=</span> <span class="nx">f</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code">
<div class="highlight"><pre> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Fprintf</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stderr</span><span class="p">,</span> <span class="s">&quot;error: %v\n&quot;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="nx">os</span><span class="p">.</span><span class="nx">Exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
<p>Запуск программы подтверждает, что файл закрыт
после записи.</p>
</td>
<td class="code">
<div class="highlight"><pre><span class="gp">$</span> go run defer.go
<span class="go">creating</span>
<span class="go">writing</span>
<span class="go">closing</span>
</pre></div>
</td>
</tr>
</table>
<p class="next">
Следующий пример: <a href="collection-functions">Функции коллекции (Collection Functions)</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/defer">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
<br/>
переведено Nick S. | <a href="https://github.com/badkaktus/gobyexample">исходники</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"os\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' f := createFile(\"/tmp/defer.txt\")\u000A defer closeFile(f)\u000A writeFile(f)\u000A}\u000A');codeLines.push('func createFile(p string) *os.File {\u000A fmt.Println(\"creating\")\u000A f, err := os.Create(p)\u000A if err != nil {\u000A panic(err)\u000A }\u000A return f\u000A}\u000A');codeLines.push('func writeFile(f *os.File) {\u000A fmt.Println(\"writing\")\u000A fmt.Fprintln(f, \"data\")\u000A');codeLines.push('}\u000A');codeLines.push('func closeFile(f *os.File) {\u000A fmt.Println(\"closing\")\u000A err := f.Close()\u000A');codeLines.push(' if err != nil {\u000A fmt.Fprintf(os.Stderr, \"error: %v\\n\", err)\u000A os.Exit(1)\u000A }\u000A}\u000A');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>