本文共 6749 字,大约阅读时间需要 22 分钟。
var v1 int//声明一个整型变量v1var v2 stringvar v3 [10]int //数组var v4 []int//数组切片var v5 struct { //结构体 f int}var v6 *int//指针var v7 map[string] int//map,ley为string,value为intvar v8 func(a int) int可以看到,变量的声明没有以分号 ; 作为结束符。var关键字也可一次定义多个变量:
var ( v1 int v2 string)变量的初始化
var v1 int = 10 // 正确的使用方式1var v2 = 10 // 正确的使用方式2,编译器可以自动推导出 v2的类型v3 := 10 // 正确的使用方式3,编译器可以自动推导出 v3的类型
var i inti := 2//错误的做法
变量赋值 var v10 int//先声明,再赋值v10 = 123i, j = 2, 3//Go支持多重赋值由多重赋值我们可以很方便的交换两个数的值
i, j = j, i//编译器会先计算等号右边的值,再为左边的赋值匿名变量 Go语言支持多返回值和匿名变量
func GetName() (firstName, lastName, nickName string) { return "May", "Chan", "Chibi Maruko"}
_, _, nickName := GetName()常量
//以下为字面常量-123.14159265358979323846 // 浮点类型的常量3.2+12i // 复数类型的常量true // 布尔类型的常量"foo" // 字符串常量常量的定义
const Pi float64 = 3.14159265358979323846const zero = 0.0 // 无类型浮点常量const ( size int64 = 1024 eof = -1 // 无类型整型常量)const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值const a, b, c = 3, 4, "foo"// a = 3, b = 4, c = "foo", 无类型整型和字符串常量如果常量在定义时没有限定类型,那么该常量 是一个 字面常量。常量定义的右值也可以是一个在编译期运算的常量表达式,如:
const mask = 1 << 3
const Home = os.GetEnv("HOME")预定义常量
const ( // iota被重设为 0c0 = iota // c0 == 0c1 = iota // c1 == 1c2 = iota // c2 == 2)const (a = 1 << iota // a == 1 (iota在每个const开头被重设为 0)b = 1 << iota // b == 2c = 1 << iota // c == 4)const (u = iota * 42 // u == 0v float64 = iota * 42 // v == 42.0w = iota * 42 // w == 84)const x = iota // x == 0 ( 因为 iota又被重设为 0了 )const y = iota // y == 0 ( 同上)如果两个const的赋值语句的表达式是一样的,那么可以省略后一个赋值表达式。因此,上面的前两个const语句可简写为:
const ( // iota被重设为 0c0 = iota // c0 == 0c1 // c1 == 1c2 // c2 == 2)const (a = 1 <
const (Sunday = iotaMondayTuesdayWednesdayThursdayFridaySaturdaynumberOfDays // 这个常量没有导出)同Go语言的其他符号( symbol)一样,以 大写字母开头的常量在包外可见。以上例子中numberOfDays为包内私有,其他符号则可被其他包访问。
var v1 boolv1 = truev2 := (1 == 2) // v2也会被推导为 bool类型布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换。以下的示例是一些错误的用法,会导致编译错误:
var b boolb = 1 // 编译错误b = bool(1) // 编译错误以下的用法才是正确的:var b boolb = (1!=0) // 编译正确fmt.Println("Result:", b) // 打印结果为 Result: true整型
var value2 int32value1 := 64 // value1将会被自动推导为 int类型value2 = value1 // 编译错误使用强制类型转换可以解决这个编译错误: value2 = int32(value1) // 编译通过 当然,开发者在做强制类型转换时,需要注意数据长度被截短而发生的数据精度损失(比如将浮点数强制转为整数)和值溢出(值超过转换的目标类型的值范围时)问题。
5 % 3 // 结果为: 2
i, j := 1, 2if i == j { fmt.Println("i and j are equal.")}两个不同类型的整型数不能直接比较,比如int8类型的数和int类型的数不能直接比较,但各种类型的整型变量都可以直接与字面常量( literal)进行比较,比如:
var i int32var j int64i, j = 1, 2if i == j { // 编译错误 fmt.Println("i and j are equal.")}if i == 1 || j == 2 { // 编译通过 fmt.Println("i and j are equal.")}
var fvalue1 float32fvalue1 = 12fvalue2 := 12.0 // 如果不加小数点, fvalue2会被推导为整型而不是浮点型对于以上例子中类型被自动推导的fvalue2 ,需要注意的是其类型将被自动设为float64,而不管赋给它的数字是否是用32位长度表示的。因此,对于以上的例子,下面的赋值将导致编译 错误:
fvalue1 = fvalue2而必须使用这样的强制类型转换:
fvalue1 = float32(fvalue2)2. 浮点数比较 因为浮点数不是一种精确的表达方式,所以像整型那样直接用==来判断两个浮点数是否相等是不可行的,这可能会导致不稳定的结果。 下面是一种推荐的替代方案:
import "math"// p为用户自定义的比较精度,比如0.00001func IsEqual(f1, f2, p float64) bool { return math.Fdim(f1, f2) < p}复数类型 复数实际上由两个实数(在计算机中用浮点数表示)构成,一个表示实部( real),一个表示虚部( imag)。如果了解了数学上的复数是怎么回事,那么Go语言的复数就非常容易理解了。 1. 复数表示 复数表示的示例如下:
var value1 complex64 // 由2个float32构成的复数类型value1 = 3.2 + 12ivalue2 := 3.2 + 12i // value2 是complex128类型value3 := complex(3.2, 12) // value3 结果同 value22. 实部与虚部 对于一个复数z = complex(x, y) ,就可以通过Go语言内置函数real(z) 获得该复数的实 部,也就是x,通过imag(z) 获得该复数的虚部,也就是y。 更多关于复数的函数,请查阅math/cmplx标准库的文档。 字符串
var str string // 声明一个字符串变量str = "Hello world" //字符串赋值ch := str[0] // 取字符串的第一个字符fmt.Printf("The length of \"%s\" is %d \n", str, len(str))fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)输出结果为:
The length of "Hello world" is 11The first character of "Hello world" is H.字符串的内容可以用类似于数组下标的方式获取,但与数组不同,字符串的内容不能在初始化后被修改,比如以下的例子:
str := "Hello world" // 字符串也支持声明时进行初始化的做法str[0] = 'X' // 编译错误在这个例子中我们使用了一个Go语言内置的函数len() 来取字符串的长度。这个函数非常有用,我们在实际开发过程中处理字符串、数组和切片时将会经常用到。 本节中我们还顺便示范了Printf() 函数的用法。有C语言基础的读者会发现, Printf() 函数的用法与C语言运行库中的printf() 函数如出一辙。读者在以后学习更多的Go语言特性时,可以配合使用Println() 和Printf() 来打印各种自己感兴趣的信息,从而让学习过程更加直观、有趣。 Go编译器支持UTF-8的源代码文件格式。这意味着源代码中的字符串可以包含非ANSI的字符,比如“Hello world. 你好,世界!”可以出现在Go代码中。但需要注意的是,如果你的Go代 码需要包含非ANSI字符,保存源文件时请注意编码格式必须选择UTF-8。特别是在Windows下一般编辑器都默认存为本地编码,比如中国地区可能是GBK编码而不是UTF-8,如果没注意这点在编译和运行时就会出现一些意料之外的情况。 字符串的编码转换是处理文本文档(比如TXT、 XML、 HTML等)非常常见的需求,不过可惜的是Go语言仅支持UTF-8和Unicode编码。对于其他编码, Go语言标准库并没有内置的编码转换支持。不过,所幸的是我们可以很容易基于iconv库用Cgo包装一个。这里有一个开源项目: https://github.com/xushiwei/go-iconv。
str := "Hello, 世界"n := len(str)for i := 0; i < n; i++ { ch := str[i] // 依据下标取字符串中的字符,类型为 byte fmt.Println(i, ch)}这个例子的输出结果为:
0 721 1012 1083 1084 1115 446 327 2288 1849 15010 23111 14912 140可以看出,这个字符串长度为13。尽管从直观上来说,这个字符串应该只有9个字符。这是因为每个中文字符在UTF-8中占3个字节,而不是1个字节。 另一种是以Unicode字符遍历:
str := "Hello, 世界"for i, ch := range str { fmt.Println(i, ch)//ch的类型为 rune}输出结果为:
0 721 1012 1083 1084 1115 446 327 1999010 30028以Unicode字符方式遍历时,每个字符的类型是rune(早期的Go语言用int类型表示Unicode 字符),而不是byte。