教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 07.变量声明须一致

07.变量声明须一致

发布时间:2022-03-04   编辑:jiaochengji.com
教程集为您提供07.变量声明须一致等资源,欢迎您收藏本站,我们将为您提供最新的07.变量声明须一致资源
<h1>本文视频地址</h1>

Go 语言,使用变量之前需要先进行变量的声明。

<pre><code class="lang-go hljs">var s string = “Golang" n := 666</code></code></pre>

Go 语言有两类变量

包级别(package varible):在 package 级别可见的变量。如果是导出变量,该变量也可以被视为全局变量;

<pre><code class="lang-go hljs"> 局部变量(local varible):函数或方法体内声明的变量,仅在函数或方法体内可见。 </code></code></pre><h1>1. 包级别变量</h1>

包级变量使用var 关键字的变量声明形式,从变量声明的时候是否延迟初始化这个角度对包级变量进行一次分类。

<h3>1). 声明并同时显式初始化</h3><pre><code class="lang-go hljs"> /$GOROOT/src/io/pipe.go var ErrClosedPipe = errors.New("io: read/write on closed pipe") //$GOROOT/src/io/io.go var EOF = errors.New("EOF”)</code></code></pre>

上面,对于变量声明的同时进行显式初始化的这类包级变量,格式:

<pre><code class="lang-go hljs"> var 变量名 = 初始化表达式</code></code></pre>

编译器会自动根据等号右侧 初始化表达式 结果值的类型确定左侧声明的变量的类型。

<pre><code class="lang-go hljs"> var num = 16 var pi = 3.14</code></code></pre>

Go 会为包级变量设置默认类型,对于未显式赋予类型的整型变量 num,编译器会设置默认 类型 int;而浮点型变量 f 的默认类型则为 float64。如果不想使用默认类型,而是要显式为 num 和 pi 指定类型。

<pre><code class="lang-go hljs"> var num = int32(16) var pi = float64(3.14)</code></code></pre>

上面是默认类型和显式指定类型两种声明形式,尤其是在将这些变量放在一个 var 块中声明时

<pre><code class="lang-go hljs"> var ( num = 17 pi = float32(3.14) )</code></code></pre>

### 2) 延迟初始化

<pre><code class="lang-go hljs">有时候,声明并不立即显式初始化的包级变量,虽然没有显式初始化,Go 语言也会让这些变量拥有初始的“零值”。如果是自定义的类型,保证其零值可用是非常必要的,形式如下:</code></code></pre><pre><code class="lang-go hljs"> var a int32 var f float64</code></code></pre><h3>3) 声明聚类与就近原则</h3>

Go 语言提供 var 块用于将多于一个的变量声明放在一起,我们习惯:
1 将同一类的变量声明放在一个 var 块中,不同类的声明放在不同的 var 块中;

<pre><code class="lang-go hljs"> 2 将延迟初始化的变量声明放在一个 var 块,而将声明且显式初始化的变量放在另一个 var 块中。 </code></code></pre>

Go 标准库中的代码:

<pre><code class="lang-go hljs">// $GOROOT/src/net/http/server.go var ( bufioReaderPool sync.Pool bufioWriter2kPool sync.Pool bufioWriter4kPool sync.Pool ) var copyBufPool = sync.Pool{ New: func() interface{} { b := make([]byte, 32*1024) return &b }, }</code></code></pre>

copyBufPool 变量没有放入 var 块就是因为它的声明是带有显式初始化的,而 var 块中的变量声明都是延迟初始化的。

<pre><code class="lang-go hljs">// $GOROOT/src/net/net.go var ( // aLongTimeAgo is a non-zero time, far in the past, used for // immediate cancelation of dials. aLongTimeAgo = time.Unix(1, 0) // nonDeadline and noCancel are just zero values for // readability with functions taking too many parameters. noDeadline = time.Time{} noCancel = (chan struct{})(nil) ) var threadLimit chan struct{}</code></code></pre>

hreadLimit 单独放在 var 块外面,它是延迟初始化的变量声明,它与以上的 var 块中时间限制的变量也有所不同。

变量声明最佳实践中还有一个原则-就近原则,如果一个包级变量在包内部多处使用,放在源文件头部声明比较恰当直观。

<pre><code class="lang-go hljs">/ $GOROOT/src/net/http/request.go // ErrNoCookie is returned by Request's Cookie method when a cookie is not found. var ErrNoCookie = errors.New("http: named cookie not present") // Cookie returns the named cookie provided in the request or // ErrNoCookie if not found. // If multiple cookies match the given name, only one cookie will // be returned. func (r *Request) Cookie(name string) (*Cookie, error) { for _, c := range readCookies(r.Header, name) { return c, nil } return nil, ErrNoCookie }</code></code></pre><h1>2. 局部变量的声明形式</h1>

比上面的包级别变量,局部变量多了短变量声明形式,局部变量采用最多的一种声明形式。
##### 1) 对于延迟初始化的局部变量声明,用带有 var 的声明形式。

<pre><code class="lang-go hljs"> // $GOROOT/src/strings/replace.go func (r *byteReplacer) Replace(s string) string { var buf []byte // 延迟初始化 for i := 0; i < len(s); i { b := s[i] if r[b] != b { if buf == nil { buf = []byte(s) } buf[i] = r[b] } } if buf == nil { return s } return string(buf) }</code></code></pre><pre><code class="lang-go hljs"> var err error 这也是我们日常常见的声明方式 </code></code></pre>

短变量声明形式是局部变量最常用的声明形式,在 Go 标准库代码中广泛使用。

<pre><code class="lang-go hljs"> num := 17 //默认类型 pi := float32(3.14) //显示转型 // $GOROOT/src/net/net.go func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) { if wv, ok := w.(buffersWriter); ok { return wv.writeBuffers(v) } for _, b := range *v { nb, err := w.Write(b) n = int64(nb) if err != nil { v.consume(n) return n, err } } v.consume(n) return n, nil }</code></code></pre>

我们看到Go源代码net中,if wv, ok := w.(buffersWriter); ok和for _, b := range *v都使用了短变量声明形式,这也体现出“就近”原则,让变量的作用域最小化。

设计良好的函数/方法的原则是“单一职责”,因此每个函数/方法规模都不大,很少需要应用 var 块来声明局部变量,如果你在声明局部变量时遇到这种场景,那就使用 var 块来声明多于一个的局部变量吧。看一下Go标准库中的源代码是这么使用的:

<pre><code class="lang-go hljs">// $GOROOT/src/net/dial.go func (r *Resolver) resolveAddrList(ctx context.Context, op, network, addr string, hint Addr) (addrList, error) { ... ... var ( tcp *TCPAddr udp *UDPAddr ip *IPAddr wildcard bool ) ... ... }</code></code></pre>

<span class="img-wrap"></span>


到此这篇关于“07.变量声明须一致”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
VBScript 变量
java常量与变量的学习笔记
07.变量声明须一致
golang重复声明变量
php static静态变量修饰符的用法详解
VBS脚本定义和使用变量
javascript 变量详解
php变量名由什么组成
PHP函数类型声明总结
Python基本语法与变量的相关介绍

[关闭]
~ ~