GO学习笔记——GO语言变量与变量定义(5)

上一篇说完了GO语言的基本数据类型,这一篇就来说说怎么定义各种不同类型的变量吧

GO语言中变量定义需要使用关键字var,并且GO语言中定义变量是和C++定义变量相反的,C++是变量类型在前,变量名在后;而GO是变量名在前,变量类型在后。这是它们之间在定义变量时最明显的不同

1. 只声明不定义

var a int

这个时候,又不一样了。我们没有给a变量初始化,那a的值到底是什么呢?我们可以来看一下

func main() {
	var a int
	fmt.Println(a)
}

//输出结果如下
0

Process finished with exit code 0

好像和C++不太一样?C++中如果一个局部变量只是声明没有初始化的话,那么它会是一个随机值。

GO语言有一个变量零值的概念,就是在只声明而不赋值变量的时候,变量的值会默认给一个零值,这个零值不是随机值。

  • 数值类型(int,float32等)的零值都是0
  • string的零值就是一个空字符串
  • bool的零值就是false

这几个类型的零值需要记住。

func main() {
	var a int32
	var b float32
	var c bool
	var d complex64
	var e string
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
	fmt.Printf("%q",e)    //%q可以打出字符串的引号,方便我们看
}

//输出结果如下

0
0
false
(0+0i)
""

2. 对一个变量进行赋值

func main() {
	var a int32
	a = 5
        fmt.Println(a,b,c)
}

3. 声明和赋值同时进行

func main() {
	var a int = 5
        fmt.Println(a)
}

4. 分组声明

func main() {
	var (
		a int = 5
		b bool = true
		c string = "pigff"
	)
        fmt.Println(a,b,c)
}

5. 同一行声明多个变量并赋值(当然也可以不赋值)

func main() {
	var a,b,c int32 = 1,2,3
        fmt.Println(a,b,c)
}

如上,一次定义了三个变量a,b,c,顺序给它们赋值为1,2,3

这里有一个问题,如果我们给c赋值为3.1,也就是将一个浮点类型赋值给int32类型,会怎么样?

func main() {
	var a,b,c int32 = 1,2,3.1
        fmt.Println(a,b,c)
}

显而易见会报错

.\main.go:6:24: constant 3.1 truncated to integer

那么,问题来了,这个int32在这边不是很束缚手脚吗,我一次要定义多个变量,但是我却只能一次定义多个相同类型的变量,这很束缚我们的程序。

于是GO和其他很多编程语言一样都这么觉得,变量的类型我完全可以让编译器去自己推断啊,比如3.1,编译器就会自己给他推断成浮点型而不会是int32,因此,我们完全可以省略这个束缚手脚的类型声明。

func main() {
	var a,b,c  = 1,2,3.1
	fmt.Println(a,b,c)
}

//输出结果

1 2 3.1

再复杂编译器都可以给我们推断出来

func main() {
	var a,b,c,d,e  = 1,3.1,3+4i,true,"pigff"
	fmt.Println(a,b,c,d,e)
}

//输出结果
1 3.1 (3+4i) true pigff

那么编译给我们推断的这些类型到底是什么呢?我们可以来看一下

func main() {
	var a,b,c,d,e  = 1,3.1,3+4i,true,"pigff"
	fmt.Print("a的类型是: ")
	fmt.Println(reflect.TypeOf(a))
	fmt.Print("b的类型是: ")
	fmt.Println(reflect.TypeOf(b))
	fmt.Print("c的类型是: ")
	fmt.Println(reflect.TypeOf(c))
	fmt.Print("d的类型是: ")
	fmt.Println(reflect.TypeOf(d))
	fmt.Print("e的类型是: ")
	fmt.Println(reflect.TypeOf(e))
}

//输出结果

a的类型是: int
b的类型是: float64
c的类型是: complex128
d的类型是: bool
e的类型是: string
  • 编译器推断的整型是int,因为我们的机器是64位的,所以这个int表示的其实是int64
  • 编译器推断的浮点类型是float64,因为我们的机器是64位的,而不是float32
  • 编译器推断的复数类型是complex128,因为我们的机器是64位的,而不是complex64
  • 编译器直接推断出true是bool类型
  • 编译器直接推断出"pigff"是string类型

C++11中的auto关键字可以做到这一点,当然没有GO这样简单,因为毕竟还要写一个auto关键字,这也是GO语法简单的一个表现

6.更加简单的声明且赋值写法

我们可以把上面的赋值语句再简单地改一下。

每次都要写一个var关键字是不是很烦?我们可以在局部变量中省略这个关键字。

注意如果这个变量是在函数体外定义的,那么就必须要加上var关键字。也因此,下面的简化写法只用于在函数体内定义的局部变量

func main() {
	a,b,c,d,e  := 1,3.1,3+4i,true,"pigff"
	fmt.Println(a,b,c,d,e)
}

如上这样是可以的,用 : 来简化变量的定义,这个和使用var关键字的效果是一样的。

但是一旦一个变量通过这样来定义了,就不可以再使用:,因为这会是一个重复定义

func main() {
	a := 1
	a := 5
	fmt.Println(a)
}

会报出如下的错误

.\main.go:9:4: no new variables on left side of :=

就像一开始说的,不能在函数体外这么使用

import (
	"fmt"
)

a := 1
func main() {
	fmt.Println(a)
}

这个错误标记在了上面import的右括号上,但是实际还是错在这个赋值语句

.\main.go:7:1: syntax error: non-declaration statement outside function body

 

猜你喜欢

转载自blog.csdn.net/lvyibin890/article/details/83142931