This commit is contained in:
github-actions[bot]
2022-08-04 07:15:39 +00:00
parent ca571eb691
commit b706f63726
34 changed files with 9 additions and 60436 deletions

View File

@@ -170,8 +170,8 @@
<ul>
<li>译者柴树杉Github <a href="https://github.com/chai2010">@chai2010</a>Twitter <a href="https://twitter.com/chaishushan">@chaishushan</a></li>
<li>译者Xargin, <a href="https://github.com/cch123">https://github.com/cch123</a></li>
<li>译者CrazySssst</li>
<li>译者foreversmart <a href="mailto:njutree@gmail.com">njutree@gmail.com</a></li>
<li>译者CrazySssst, <a href="https://github.com/CrazySssst">https://github.com/CrazySssst</a></li>
<li>译者foreversmart,<a href="https://github.com/foreversmart">https://github.com/foreversmart</a> <a href="mailto:njutree@gmail.com">njutree@gmail.com</a></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="前言"><a class="header" href="#前言">前言</a></h1>
<h2 id="go语言起源"><a class="header" href="#go语言起源">Go语言起源</a></h2>
@@ -3361,9 +3361,7 @@ Title: {{.Title | printf &quot;%.64s&quot;}}
Age: {{.CreatedAt | daysAgo}} days
{{end}}`
</code></pre>
<p>{% endraw %}</p>
<p>这个模板先打印匹配到的issue总数然后打印每个issue的编号、创建用户、标题还有存在的时间。对于每一个action都有一个当前值的概念对应点操作符写作“.”。当前值“.”最初被初始化为调用模板时的参数在当前例子中对应github.IssuesSearchResult类型的变量。模板中<code>{{.TotalCount}}</code>对应action将展开为结构体中TotalCount成员以默认的方式打印的值。模板中<code>{{range .Items}}</code><code>{{end}}</code>对应一个循环action因此它们之间的内容可能会被展开多次循环每次迭代的当前值对应当前的Items元素的值。</p>
<p>{% endraw %}</p>
<p>在一个action中<code>|</code>操作符表示将前一个表达式的结果作为后一个函数的输入类似于UNIX中管道的概念。在Title这一行的action中第二个操作是一个printf函数是一个基于fmt.Sprintf实现的内置函数所有模板都可以直接使用。对于Age部分第二个动作是一个叫daysAgo的函数通过time.Since函数将CreatedAt成员转换为过去的时间长度</p>
<pre><code class="language-Go">func daysAgo(t time.Time) int {
return int(time.Since(t).Hours() / 24)
@@ -3436,7 +3434,6 @@ var issueList = template.Must(template.New(&quot;issuelist&quot;).Parse(`
&lt;/table&gt;
`))
</code></pre>
<p>{% endraw %}</p>
<p>下面的命令将在新的模板上执行一个稍微不同的查询:</p>
<pre><code>$ go build gopl.io/ch4/issueshtml
$ ./issueshtml repo:golang/go commenter:gopherbot json encoder &gt;issues.html
@@ -3464,7 +3461,6 @@ $ ./issueshtml repo:golang/go commenter:gopherbot json encoder &gt;issues.html
}
}
</code></pre>
<p>{% endraw %}</p>
<p>图4.6显示了出现在浏览器中的模板输出。我们看到A的黑体标记被转义失效了但是B没有。</p>
<p><img src="ch4/../images/ch4-06.png" alt="" /></p>
<p>我们这里只讲述了模板系统中最基本的特性。一如既往,如果想了解更多的信息,请自己查看包文档:</p>
@@ -8528,11 +8524,9 @@ gopl.io/ch7/xmlselect
<pre><code>$ go list -f '{{join .Deps &quot; &quot;}}' strconv
errors math runtime unicode/utf8 unsafe
</code></pre>
<p>{% endraw %}</p>
<p>译注上面的命令在Windows的命令行运行会遇到<code>template: main:1: unclosed action</code>的错误。产生这个错误的原因是因为命令行对命令中的<code>&quot; &quot;</code>参数进行了转义处理。可以按照下面的方法解决转义字符串的问题:</p>
<pre><code>$ go list -f &quot;{{join .Deps \&quot; \&quot;}}&quot; strconv
</code></pre>
<p>{% endraw %}</p>
<p>下面的命令打印compress子目录下所有包的导入包列表</p>
<pre><code>$ go list -f '{{.ImportPath}} -&gt; {{join .Imports &quot; &quot;}}' compress/...
compress/bzip2 -&gt; bufio io sort
@@ -8541,11 +8535,9 @@ compress/gzip -&gt; bufio compress/flate errors fmt hash hash/crc32 io time
compress/lzw -&gt; bufio errors fmt io
compress/zlib -&gt; bufio compress/flate errors fmt hash hash/adler32 io
</code></pre>
<p>{% endraw %}</p>
<p>译注Windows下有同样有问题要避免转义字符串的干扰</p>
<pre><code>$ go list -f &quot;{{.ImportPath}} -&gt; {{join .Imports \&quot; \&quot;}}&quot; compress/...
</code></pre>
<p>{% endraw %}</p>
<p><code>go list</code>命令对于一次性的交互式查询或自动化构建或测试脚本都很有帮助。我们将在11.2.4节中再次使用它。每个子命令的更多信息,包括可设置的字段和意义,可以用<code>go help list</code>命令查看。</p>
<p>在本章我们解释了Go语言工具中除了测试命令之外的所有重要的子命令。在下一章我们将看到如何用<code>go test</code>命令去运行Go语言程序中的测试代码。</p>
<p><strong>练习 10.4</strong> 创建一个工具,根据命令行指定的参数,报告工作区所有依赖包指定的其它包集合。提示:你需要运行<code>go list</code>命令两次一次用于初始化包一次用于所有包。你可能需要用encoding/json§4.5包来分析输出的JSON格式的信息。</p>
@@ -8979,18 +8971,15 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
<pre><code>$ go list -f={{.GoFiles}} fmt
[doc.go format.go print.go scan.go]
</code></pre>
<p>{% endraw %}</p>
<p>TestGoFiles表示的是fmt包内部测试代码以_test.go为后缀文件名不过只在测试时被构建</p>
<pre><code>$ go list -f={{.TestGoFiles}} fmt
[export_test.go]
</code></pre>
<p>{% endraw %}</p>
<p>包的测试代码通常都在这些文件中不过fmt包并非如此稍后我们再解释export_test.go文件的作用。</p>
<p>XTestGoFiles表示的是属于外部测试包的测试代码也就是fmt_test包因此它们必须先导入fmt包。同样这些文件也只是在测试时被构建运行</p>
<pre><code>$ go list -f={{.XTestGoFiles}} fmt
[fmt_test.go scan_test.go stringer_test.go]
</code></pre>
<p>{% endraw %}</p>
<p>有时候外部测试包也需要访问被测试包内部的代码例如在一个为了避免循环导入而被独立到外部测试包的白盒测试。在这种情况下我们可以通过一些技巧解决我们在包内的一个_test.go文件中导出一个内部的实现给外部测试包。因为这些代码只有在测试时才需要因此一般会放在export_test.go文件中。</p>
<p>例如fmt包的fmt.Scanf函数需要unicode.IsSpace函数提供的功能。但是为了避免太多的依赖fmt包并没有导入包含巨大表格数据的unicode包相反fmt包有一个叫isSpace内部的简易实现。</p>
<p>为了确保fmt.isSpace和unicode.IsSpace函数的行为保持一致fmt包谨慎地包含了一个测试。一个在外部测试包内的白盒测试是无法直接访问到isSpace内部函数的因此fmt通过一个后门导出了isSpace函数。export_test.go文件就是专门用于外部测试包的后门。</p>