This commit is contained in:
Unknown
2013-04-23 14:59:41 -04:00
parent 712d9f9ed1
commit 47cb524ad5

View File

@@ -1,26 +1,36 @@
##啊哦,亲,你看得也太快了。。。还没翻译完呢 0 0
要不等到 ***2013 年 4 月 25 日*** 再来看看吧~~
这里还有一些其它的学习资源噢~
- [《Go编程基础》](https://github.com/Unknwon/go-fundamental-programming):已更新至 [第9课](https://github.com/Unknwon/go-fundamental-programming/blob/master/lecture9/lecture9.md)
- [《Go Web编程》](https://github.com/astaxie/build-web-application-with-golang)
神马?你说你不想学习?那好吧,去逛逛论坛看看行情也行~
- [Golang中文社区](http://bbs.mygolang.com/forum.php)
- [Go语言学习园地](http://studygolang.com/)
- [Golang中国](http://golang.tc)
#4.4 变量 #4.4 变量
#4.4.1 简介
声明变量的一般形式是使用 `var` 关键字:`var identifier type`
##4.4.1 介绍 需要注意的是Go 和许多编程语言不同它在声明变量时将变量的类型放在变量的名称之后。Go 为什么要选择这么做呢?
声明变量的一般形式是使用关键字 ***var*** *var identifier type* 首先,它是为了避免像 C 语言中那样含糊不清的声明形式,例如:`int* a, b;`。在这个例子中,只有 a 是指针而 b 不是。如果你想要这两个变量都是指针,则需要将它们分开书写(你可以在该页面找到有关于这个话题的更多讨论:[http://blog.golang.org/2010/07/gos-declaration-syntax.html](http://blog.golang.org/2010/07/gos-declaration-syntax.html))。
值得注意的是,类型是写在要标识的变量之后,着不同去几乎其他任何编程语言。为什么 Go 设计者选择了这个约定? 而在 Go 中,则可以和轻松地将它们都声明为指针类型:`var a, b *int`
首先它消除了像在C语言式声明的一些模糊在写 `int* a, b` 其次,这种语法能够按照从左至右的顺序阅读,使得代码更加容易理解。
只有 a 是一个指针,而 b 不是。为了表示他俩都是指针,必须重复星号。(这个主题有一个很长的讨论,详见:<http://blog.golang.org/2010/07/gos-declaration-syntax.html> 示例:
但是在 Go 语言中,他们可以同时声明,如: `var a, b *int`
其次,这样从左到右,便于阅读。
一些例子:
var a int var a int
var b bool var b bool
var str string var str string
也可以写成: 也可以写成这种形式
var ( var (
a int a int
@@ -28,34 +38,32 @@
str string str string
) )
这种形式主要用于全局变量声明 这种因式分解关键字的写法一般用于声明全局变量。
当一个变量被声明,根据它的类型自动包含默认值或 null int 的默认值为 0float 的默认值为 0.0bool 的默认值为 false string 的默认值为空字符串`string("")`,指针的默认值为 nil零值的结构体等等 当一个变量被声明之后系统自动赋予它该类型的零值int 为 0flost 为 0.0bool 为 falsestring 为空字符串,指针为 nil。记住所有的内存在 Go 中都是经过初始化的。
_所有变量在 Go 语言中都初始化._ 变量的命名规则遵循骆驼命名法,即首个单词小写,每个新单词的首字母大写,例如:`numShips`, `startDate`
变量的标识符命名遵循驼峰命名法(以小写字母开头,其后每个单词以大写字母开头),如: numShipsstartDate 但如果你的全局变量希望能够被外部包所使用,则需要将首个单词的首字母也大写(第 4.2 节:可见性规则)
但是如果变量要被导出,它必须以大写字母开头(可见性规则 §4.2 一个变量(常量、类型或函数)在程序中都有一定的作用范围,称之为作用域。如果一个变量在函数体外声明,则被认为是全局变量,可以在整个包甚至外部包(被导出后)使用,不管你声明在哪个源文件里或在哪个源文件里调用该变量
一个变量(常量,类型,函数)只作用于程序的一定范围,称为作用域在函数外声明的变量(换句话说在顶层)是全局(或包)变量:他们在整个包内都是可见的 在函数体内声明的变量称之为局部变量,它们的作用域在函数体内,参数和返回值变量也是局部变量。在第 5 章,我们将会学习到像 if 和 for 这些控制结构,而在这些结构中声明的变量的作用域只在相应的代码块内。一般情况下,局部变量的作用域可以通过代码块(用大括号括起来的部分)判断
在函数内声明的变量有本地作用范围:只能在函数内被调用,参数和返回值也一样。在第 5 章将遇到控制语句如 if 和 for一个变量在这样的机构中被定义也只能在它内部被调用构造范围。大多数情况你可以将作用域理解为代码块`{ }`包围)内的变量声明 尽管变量的标识符必须是唯一的,但你可以在某个代码块的内层代码块中使用相同名称的变量,则此时外部的同名变量将会暂时隐藏(结束内部代码块的执行后隐藏的外部同名变量又会出现,而内部同名变量则被释放),你任何的操作都只会影响内部代码块的局部变量
当然,标识符必须唯一,在一个代码块中的一个标识符可以在它的内部代码块中重新声明:在这个代码块(惟独这里)内,重新声明名称相同的变量有更高的优先级,请小心使用,以避免 subtle 错误见§16.1 变量可以编译期间就被赋值,赋值给变量使用运算符等号 `=`,当然你也可以在运行时对变量进行赋值操作
变量可以在编译期得到他们的值(这被称为赋值,并且使用赋值操作符 `=`),当然,这个值在运行时也可以被计算和改变。 示例:
例子
a = 15 a = 15
b = false b = false
一般情况,当变量 a 和变量 b 是相同类型时,变量 b 可以赋值给变量 a 如: `a = b` 一般情况下,只有类型相同的变量之间才可以相互赋值,例如:`a = b`
声明赋值(初始化)也可以同时进行,一般的格式如下: 声明赋值(初始化)语句也可以组合起来。
例:
var identifier [type] = value var identifier [type] = value
var a int = 15 var a int = 15
@@ -63,13 +71,13 @@ _所有变量在 Go 语言中都初始化._
var b bool = false var b bool = false
var str string = “Go says hello to the world!” var str string = “Go says hello to the world!”
但是 Go 编译器足够智能得从一个变量的值推导出他的类型(动态的,也被称为动态类型推断,有点像脚本语言 Python 和 Ruby但是只在运行时执行所以如下的形式忽略类型也是正确的 但是 Go 编译器的智商已经高到可以根据变量的值来自动推断其类型,这有点像 Ruby 和 Python 这类动态语言,只不过它们是在运行时进行推断,而 Go 是在编译时就已经完成推断过程。因此,你还可以使用下面的这些形式来声明及初始化变量
var a = 15 var a = 15
var b = false var b = false
var str = “Go says hello to the world!” var str = “Go says hello to the world!”
var ( var (
a = 15 a = 15
@@ -79,39 +87,41 @@ _所有变量在 Go 语言中都初始化._
city string city string
) )
当你想使变量的类型与推断不同时,这仍然是有用的,如:`var n int64 = 2` 不过自动推断类型并不是任何时候都适用的,当你想要给变量的类型并不是自动推断出的某种类型时,你还是需要显式指定变量的类型,例如:`var n int64 = 2`
但是一个表达式如 `var a` 是不正确的,因为编译器没有 a 的类型线索。变量也可以在运行时计算表达式,如: 然而,`var a` 这种语法是不正确的,因为编译器没有任何可以用于自动推断类型的依据。变量的类型也可以在运行时实现自动推断,例如:
var ( var (
HOME = os.Getenv("HOME") HOME = os.Getenv(HOME)
USER = os.Getenv("USER") USER = os.Getenv(USER)
GOROOT = os.Getenv("GOROOT") GOROOT = os.Getenv(GOROOT)
) )
个 var 的语法主要用于全局级和包级,在函数中,它被这个短声明语法 `:=` 代替(见 § 4.4 种写法主要用于声明包级别的全局变量,当你在函数体内声明局部变量时,应使用简短声明语法 `:=`,例如:`a := 1`
下面这个例子展示了程序运行在那种操作系统上。它有一个本地的 string 变量调用 Getenv 函数(这用来取得环境变量)来自 os 包 下面这个例子展示了如何在运行时获取所在的操作系统类型,它通过 `os` 包中的函数 `os.Getenv()` 来获取环境变量中的值,并保存到 string 类型的局部变量 `path`
Listing 4.5[goos.go](examples/chapter_4/goos.go): Example 4.5 [goos.go](examples/chapter_4/goos.go)
package main package main
import ( import (
"fmt" fmt
"os" os
) )
func main() { func main() {
var goos string = os.Getenv("GOOS") var goos string = os.Getenv(GOOS)
fmt.Printf("The operating system is: %s\n", goos) fmt.Printf(The operating system is: %s\n, goos)
path := os.Getenv("PATH") path := os.Getenv(PATH)
fmt.Printf("Path is %s\n", path) fmt.Printf(Path is %s\n, path)
} }
本例的输出根据本地环境变量的值,可能是: `The operating system is: windows`,或 `The operating system is: linux` 如果你在 Windows 下运行这段代码,则会输出 `The operating system is: windows` 以及相应的环境变量的值;如果你在 Linux 下运行这段代码,则会输出 `The operating system is: linux` 以及相应的的环境变量的值
这里Printf 被用于格式化输出(见 § 4.4.3)。 这里用到了 `Printf`格式化输出的功能(第 4.4.3)。
## 4.4.2 Value types and reference types #4.4.2 值类型和引用类型
内存在计算机程序看来好比一堆箱子也就是我们将如何写入它们叫做单词写入。以目前的操作系统开发而言所有单词具有相同的长度为32位4字节或64位8字节;所有词都有确定的*内存地址*(以十六进制数表示)。 内存在计算机程序看来好比一堆箱子也就是我们将如何写入它们叫做单词写入。以目前的操作系统开发而言所有单词具有相同的长度为32位4字节或64位8字节;所有词都有确定的*内存地址*(以十六进制数表示)。