223 lines
9.8 KiB
Plaintext
Generated
223 lines
9.8 KiB
Plaintext
Generated
<!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">"fmt"</span>
|
||
<span class="s">"os"</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">"/tmp/defer.txt"</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">"creating"</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">"writing"</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">"data"</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">"closing"</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">"error: %v\n"</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>
|