赞
踩
解释型语言和编译型语言的区别。
Go语言是编译型语言。
Go语言的特点(自带垃圾回收,天生支持并发)
最早的时候,Go所依赖的所有第三方库都在GOPATH目录下,这就导致同一个库只能保存在一个版本的代码,如果不同的项目依赖同一个库的不同版本,就没办法了。
从1.5开始引入vendor模式,如果项目目录下有vendor目录,那么go工具链就会优先使用vender内的包进行编译,测试等。
godep是一个通过vender模式实现的Go语言的第三方依赖管理工具,类似的还有社区维护的包管理工具dep。
go get github.com/tools/godep
在终端输入godep查看支持的所有命令
使用godep save
命令,会在当前项目中创建Godeps和vender两个文件夹,其中Godeps文件夹下有一个Godeps.json
的文件,里面记录了项目所依赖的包信息。vender文件夹下是项目依赖的包的源代码文件。
Go1.5版本之后开始支持,能够控制Go语言程序编译时依赖包搜索路径的优先级。
例如查找项目的某个依赖包,首先会在项目根目录下的vender
文件夹中查找,如果没有找到就会去$GOAPTH/src
目录下查找。
在Go语言中,如果导入了一个包但是没有使用该包,将被当做一个编译错误处理,这种强制规则可以有效减少不必要的依赖。goimports工具可以根据需要自动添加或者删除导入的包,许多编辑器都可集成这个工具,然后保存文件自动运行,gofmt工具可以用来格式化Go文件。
包的初始化首先是解决包级别变量的依赖顺序,然后按照包级别变量声明出现的顺序依次初始化。
包中一般含有多个go源文件,他们将按照发给编译器的顺序进行初始化,Go语言的构建工具首先会将go文件根据文件名进行排序,然后依次调用编译器编译。
init初始化函数
每个文件都可以包含多个init初始化函数,这样的初始化函数除了不能被调用或者引用外,其他行为和普通函数类似。在每个文件中的init初始化函数,在程序开始执行时按照他们声明的顺序被自动调用。
func init(){
}
每个包只会被初始化一次,如果p包导入了另一个包p,那么p在初始化的时候q就必然已经初始化过了。所以main包是最后被初始化的。
函数外面只能放标识符(变量,常量,函数,类型)的声明。
Go语言必须先声明再使用。
常量表达式的值在编译期进行计算,而不是在运行期,每种常量的潜在类型都是基础类型或数字。常量一旦赋值不可修改,值不会改变。
在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_
(下划线)组成,并且只能以字母和_
开头。 举几个例子:abc
, _
, _123
, a123
。
关键字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。
Go语言中有25个关键字:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
此外,Go语言中还有37个保留字。
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
Functions: make len cap new append copy close delete
complex real imag
panic recover
变量声明以关键字var
开头,变量类型放在变量的后面,行尾无需分号。 举个例子:
// 标准声明
var studentName string
// 批量声明
var (
age int
isOk bool
)
变量的初始化
Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0
。 字符串变量的默认值为空字符串
。 布尔型变量默认为false
。 切片、函数、指针变量的默认为nil
。出现在赋值语句的右边时,并不一定是产生两个结果,也可能产生两个结果。对于值产生一个结果的情形,map 查找失败时会返回零值,类型断言失败时会发送运行时panic异常,通道接收失败时会返回零值(阻塞不算是失败)。
var name string = "Q1mi"
var age int = 18
var name, times = "Q1mi", 20
我们可以直接将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。
var name = "Q1mi"
var age = 18
短变量声明
在函数内部,可以使用更简略的 :=
方式声明并初始化变量,函数外面不能使用简短声明。
func testNum() {
n := 10
m := 200 // 此处声明局部变量m
fmt.Println(m, n)
}
匿名变量
在使用多重赋值的时候,如果想要忽略某个值,可以使用_接收_,表示一个匿名变量。
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。在lua编程语言中,匿名变量也叫做哑元变量。
func foo() (int, string) {
return 100, "hehe"
}
func main() {
// _ 匿名变量,相当于占位符
_, str := foo()
fmt.Println(str)
}
注意事项:
:=
不能使用在函数外。_
多用于占位,表示忽略值。在赋值语句两边的变量最终的值必须有相同的数据类型。
新命名的类型提供了一个方法,用来分割不同概念的类型,这样即使他们底层类型相同也是不兼容的。
type 类型名称 底层类型
type num int
类型声明的语句一般出现在包一级,如果新创建的类型名字的首字母大写,那么在外部包也可以使用。
对于中文汉字,Unicode标志都作为小写字母处理,因此中文的命名默认不能导出。
对于每个类型T,都有一个类型转换操作T(x),将x转换成T类型,如果是指针烈性,可能要用小括号包装T,(*int)(0)。只有当两个类型的底层基础类型相同时,才允许这种转型,或者是两者都是指向相同底层结构的指针类型,这些转换值改变类型而不会影响值本身。
如果两个值有着不同的类型,则不能直接比较。编译会报错。
var c Celsius
var f Fahrenheit
fmt.Println(c == 0) // "true"
fmt.Println(f >= 0) // "true"
fmt.Println(c == f) // compile error: type mismatch
fmt.Println(c == Celsius(f)) // "true"!
对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var
换成了const
,常量在定义的时候必须赋值。
const pi = 3.1415
const e = 2.7182
声明了pi
和e
这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。
多个常量也可以一起声明:
const (
pi = 3.1415
e = 2.7182
)
const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:
const (
n1 = 100
n2
n3
)
上面示例中,常量n1
、n2
、n3
的值都是100。
常量计数器iota
iota是go语言的常量计数器,只能在常量的表达式中使用。
iota在const
关键字出现时将被重置为0,const
中每次增加一行常量声明将使iota计数一次,使用iota能简化定义,在定义枚举时很有用。
const ( n1 = iota //0 n2 //1 _ n4 //3 _ = iota KB = 1 << (10 * iota) MB = 1 << (10 * iota) GB = 1 << (10 * iota) //从这开始会溢出 TB = 1 << (10 * iota) PB = 1 << (10 * iota) ) func main(){ fmt.Println(n1) fmt.Println(n2) fmt.Println(n4) fmt.Println(KB) fmt.Println(MB) } // 输出 0 1 3 1125899906842624 1152921504606846976
%d:十进制
%o:八进制
%x:十六进制
%b:二进制
%T:输出数据类型
%c:字符
%s:字符串
%p:指针
%v:值
%#v:详细值
%f:浮点数
%t:bool值
func main() { i2 := 077 fmt.Printf("十进制:%d\n", i2) fmt.Printf("二进制:%b\n", i2) fmt.Printf("八进制:%o\n", i2) fmt.Printf("十六进制:%x\n", i2) fmt.Printf("数据类型:%T\n", i2) //强制类型转换 fmt.Printf("%d", int32(i2)) } /**十进制:63 二进制:111111 八进制:77 十六进制:3f 数据类型:int 63**/
uint8 | 无符号 8位整型 (0 到 255) |
---|---|
uint16 | 无符号 16位整型 (0 到 65535) |
uint32 | 无符号 32位整型 (0 到 4294967295) |
uint64 | 无符号 64位整型 (0 到 18446744073709551615) |
int8 | 有符号 8位整型 (-128 到 127) |
int16 | 有符号 16位整型 (-32768 到 32767) |
int32 | 有符号 32位整型 (-2147483648 到 2147483647) |
int64 | 有符号 64位整型 (-9223372036854775808 到 9223372036854775807) |
特殊整型
类型 | 描述 |
---|---|
uint | 32位操作系统上就是uint32 ,64位操作系统上就是uint64 |
int | 32位操作系统上就是int32 ,64位操作系统上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
注意: 在使用int
和 uint
类型时,不能假定它是32位或64位的整型,而是考虑int
和uint
可能在不同平台上的差异。
获取对象长度的内建len()函数返回的长度可根据不同的平台的字节长度进行变化,实际使用中,切片或map的元素数量等都可以用int来表示,但是在进行二进制传输,读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int和uint。
浮点类型
Go语言支持两种浮点类型:float32和float64,这两种浮点类型数据格式遵循IEEE754标准,float32的浮点数的最大范围是3.4e38,可以使用常量定义:math_MaxFloat32,float64的浮点数的最大范围大约是1.8e308,可以使用常量定义:math.MaxFloat64。默认是float64位类型。
%f:表示浮点数输出类型
math包中除了提供大量常用的数学函数之外,还提供了IEEE754浮点数标准中定义的特殊值的创建和测试:正无穷大和负无穷大,分别用于表示太大溢出的数字和除零的结果,NaN表示无效的除法操作0/0或者Sqrt(-1)
NaN和任何数都是不相等的(译注:在浮点数中,NaN、正无穷大和负无穷大都不是唯一 的,每个都有非常多种的bit模式表示)
数组是值类型,值传递(复制一份,在新数据上修改,原先数据不受影响)
复数
complex64和complex128,分别对
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。