变量
变量指定了某存储单元(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)
}