变量

 变量指定了某存储单元(Memory Location)的名称,该存储单元会存储特定类型的值。在 Go 中,有多种语法用于声明变量。

声明单个变量

var name type

 package main
 ​
 import "fmt"
 ​
 func main() {
     var beast string  //声明一个string类型的变量
     fmt.Println("The beast is", beast)
 }
 ​

如果变量没有被赋值,Go会自动将其初始化,赋值为空

声明变量并初始化

 // var name type = initialvalue  用于声明变量并初始化化
 ​
 func main() {
     var beast string = "黄亮"
     fmt.Println("The beast is", beast)
 }

类型推断

如果变量有初始值,go能够根据初始值来推断变量的类型,因此在变量声明时可以省略type

 func main() {
     var beast = "黄亮"
     fmt.Println("The beast is", beast)
 }

声明多个变量

 func main() {
     var beast1, age = "姜春", 18
     fmt.Println("The beast is", beast1)
     fmt.Println("The age is", age)
 }
 ​
 //如果多个变量的类型一致,可以加上type来标识
 //如 var beast1,beast2 string = "lqz","egon"
 ​
 //但是不支持这种:
     var beast string,age int

声明多个不同变量类型的正确打开方式

 package main
 ​
 import "fmt"
 ​
 func main() {
     var (
         name   = "cherry"
         age    = 18
         height = 180
     )
     fmt.Println("my name is", name, ",my age is", age, ",my height is", height)
 }

精简声明的方式

 //精简声明要求操作符`:=`左边所有的变量都有初始值,否则会报错
 ./test1.go:6:12: assignment mismatch: 2 variables but 1 values
 ​
 func main() {
     name, age = "surpass"  //错误的用法
     fmt.Println("my name is", name)
 }
 ​
 //如果变量定义了,没有被使用也会报错
 func main() {
     name, age := "surpass", 18
     fmt.Println("my name is", name)
 }
 ./test1.go:6:8: age declared and not used
 ​
 ​
 //正确的用法
 func main() {
     name, age := "surpass", 18
     fmt.Println("my name is", name, ",age is", age)
 }
 ​
 //注意,Go中不像python中那样支持单引号
:=
 func main() {
     name, age := "surpass", 18
     fmt.Println("name is", name, ",age is", age)
     name, sex := "cherry", "male"
     fmt.Println("change name is", name, "sex is", sex)
 }
 ​
 //
 name is surpass ,age is 18
 change name is cherry sex is male
 //
 ​
 ​
 //错误的示范
 func main() {
     name, age := "surpass", 18
     fmt.Println("name is", name, ",age is", age)
     name, age := "cherry", 20
     fmt.Println("change name is", name, "change age is", age)
 }
 ​
 ./test1.go:8:12: no new variables on left side of :=

在运行时给变量赋值

 func main() {
     num1, num2 := 18.1, 36.1
     maxNum := math.Max(num1, num2)
     fmt.Println("The max num is", maxNum)
 }

注意Go是强类型语言,因此不允许某一类型的变量赋值为其他类型的值。

 ​
 func main() {
     name := "surpass"
     name = 29
 }
 ​
 //
 cannot use 29 (type int) as type string in assignment
 //
 ​
 //这点与python是不一样的

go语言支持的基本变量类型

bool

数字类型

 int8, int16, int32, int64, int
 uint8, uint16, uint32, uint64, uint
 float32, float64
 complex64, complex128
 byte
 rune
string
bool
bool
 func main() {
     a := true
     b := false
     fmt.Println("a:", a, "b:", b)
     c := a && b
     fmt.Println("c:", c)
     d := a || b
     fmt.Println("d:", d)
 }

有符号整形

int8:表示 8 位有符号整型 大小:8 位 范围:-128~127

int16:表示 16 位有符号整型 大小:16 位 范围:-32768~32767

int32:表示 32 位有符号整型 大小:32 位 范围:-2147483648~2147483647

int64:表示 64 位有符号整型 大小:64 位 范围:-9223372036854775808~9223372036854775807

int:根据不同的底层平台(Underlying Platform),表示 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型。 大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。 范围:在 32 位系统下是 -2147483648~2147483647,而在 64 位系统是 -9223372036854775808~9223372036854775807。

Printfunsafe
Sizeof
 package main
 ​
 import (
     "fmt"
     "unsafe"
 )
 ​
 func main() {
     name := "surpass"
     age := 18
     fmt.Printf("name is %s,age is %d \n", name, age)
     fmt.Printf("type of name is %T,size of name is %d \n", name, unsafe.Sizeof(name))
     fmt.Printf("type of age is %T,size of age is %d \n", age, unsafe.Sizeof(age))
 }
 ​
 //
 name is surpass,age is 18 
 type of name is string,size of name is 16 
 type of age is int,size of age is 8 
 //

无符号整形

uint8:表示 8 位无符号整型 大小:8 位 范围:0~255

uint16:表示 16 位无符号整型 大小:16 位 范围:0~65535

uint32:表示 32 位无符号整型 大小:32 位 范围:0~4294967295

uint64:表示 64 位无符号整型 大小:64 位 范围:0~18446744073709551615

uint:根据不同的底层平台,表示 32 或 64 位无符号整型。 大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。 范围:在 32 位系统下是 0~4294967295,而在 64 位系统是 0~18446744073709551615。

浮点型

float32 : 32位浮点型

float64 : 64位浮点型

示范例子: 整型和浮点型的应用

 package main
 ​
 import (
     "fmt"
 )
 ​
 func main() {
     a, b := 3.46, 6.86
     fmt.Printf("type of a is %T,type of b is %T \n", a, b)
     sum1 := a + b
     diff1 := a - b
     fmt.Println("sum is", sum1, ",diff is", diff1)
 ​
     num1, num2 := 56, 86
     sum2 := num1 + num2
     diff2 := num1 - num2
     fmt.Println("sum is", sum2, ",diff is", diff2)
 }

a 和 b 的类型根据赋值推断得出。在这里,a 和 b 的类型为 float64(float64 是浮点数的默认类型)。我们把 a 和 b 的和赋值给变量 sum,把 b 和 a 的差赋值给 diff,接下来打印 sum 和 diff。no1 和 no2 也进行了相同的计算。上述程序将会输出:

 type of a is float64,type of b is float64 
 sum is 10.32 ,diff is -3.4000000000000004
 sum is 142 ,diff is -30

复数类型

complex64:实部和虚部都是 float32 类型的的复数。 complex128:实部和虚部都是 float64 类型的的复数。


内建函数 complex用于创建一个包含实部和虚部的复数。complex 函数的定义如下:

 func complex(r, i FloatType) ComplexType

示范例子:

 package main
 ​
 import (
     "fmt"
     "unsafe"
 )
 ​
 func main() {
     c := complex(3.14, -6.57)
     fmt.Printf("type of c is [%s],size of c is [%d]\n", c, unsafe.Sizeof(c))
     fmt.Println("The complex is", c)
 }

该函数的参数分别是实部和虚部,并返回一个复数类型。实部和虚部应该是相同类型,也就是 float32 或 float64。如果实部和虚部都是 float32 类型,则函数会返回一个 complex64 类型的复数。如果实部和虚部都是 float64 类型,则函数会返回一个 complex128 类型的复数。

结果:

 type of c is [%!s(complex128=(3.14-6.57i))],size of c is [16]
 The complex is (3.14-6.57i)

我们还可以用简单的语法来创建

 c := -6 + 7i

其他数据类型

 byte 是 uint8 的别名。
 rune 是 int32 的别名。

string类型

在 Golang 中,字符串是字节的集合。如果你现在还不理解这个定义,也没有关系。我们可以暂且认为一个字符串就是由很多字符组成的。我们后面会在一个教程中深入学习字符串。 下面编写一个使用字符串的程序。

 package main
 ​
 import (
     "fmt"
 )
 ​
 func main() {
     name1 := "surpass"
     name2 := "baicai"
     fmt.Println("good is", name1, "bad is", name2)
 }
 ​

类型转换

Go 有着非常严格的强类型特征。Go 没有自动类型提升或类型转换。

 // go不允许不同类型的数据类型相加,必须先类型转换
 package main
 ​
 import (  
     "fmt"
 )
 ​
 func main() {  
     i := 10
     var j float64 = float64(i) // 若没有显式转换,该语句会报错
     fmt.Println("j", j)
 }