# 03.6 Go 指针

常量是的值是不能改变的，Go使用关键字`const`定义常量。

> Tip: 通常来说，常量是全局变量。因此，当你的代码中出现大量在局部定义的常量时，你就应该考虑重新设计你的代码了。

显而易见，使用常量的好处就是保证了该值不会在程序运行过程中被修改！

严格来说，常量的值在编译期间就被确定了。在这种情况下，Go可以使用布尔类型、字符串、或者数字类型存储常量的值。

你可以使用下面的代码定义常量：

```go
const HEIGHT = 200
```

另外，你还可以一次性定义多个常量：

```go
const (
C1 = "C1C1C1"
C2 = "C2C2C2"
C3 = "C3C3C3"
)
```

下面这三种声明变量的方式在Go看来是一样的：

```go
s1 := "My String"
var s2 = "My String"
var s3 string = "My String"
```

以上三个变量的声明并没有使用`const`关键字，所以它们并不是常量。这并不意味着你不能使用相似的方式定义两个常量：

```go
const s1 = "My String"
const s2  string = "My String"
```

尽管`s1`和`s2`都是常量，但是`s2`定义时声明了其类型，意味着它比常量`s1`的定义更加严格。这是因为一个声明类型的Go常量必须遵循与声明过类型的变量相同的严格规则，换句话说，未声明类型的常量无需遵循严格规则，使用起来会更加自由。但是，即使在定义常量时没有声明其类型，Go会根据其值判断其类型，因为你不想在使用该常量时考虑所有的规则。下面我们将用一个简单的例子来说明，当你为常量赋予具体类型时会遇到哪些问题:

```go
const s1 = 123
const s2 float64 = 123 //注意这里是float64
var v1 float32 = s1*12
var v2 float32 = s2*12
```

编译器正常通过`v1`的声明及初始化，但是由于`s2`和`v2`的类型不同，编译器就会报错：

```bash
$ go run a.go
$ command-line-argument
./a.go:12:6: canot use s2 * 12 (type float64) as type float32 in assignment
```

代码建议：如果你要用到许多常量，最好将它们定义到同一个包或者结构体中。
