yyyzyyyz

二、变量

1 定义单个变量

func main(){
	// 定义变量的第一种方法:全定义 var name type/var关键字 变量名 变量类型
	// var name type = initialvalue  该语法可以声明并初始化
	var age int = 10 // 变量如果声明就必须在后面使用,否则会报错
	fmt.Println(age)

	// 定义变量的第二种方法:类型推导 var name = initialvalue  var关键字 变量名 = 值
	// Go 能够自动推断具有初始值的变量的类型
	var a = 50
	fmt.Println(a)
	fmt.Printf("%T", a) // %T 打印变量a的类型
    
    // 定义变量的第三种方法:简略声明 var和类型都不写
    // 简短声明要求 := 操作符左边的所有变量都有初始值
	b:=20
	fmt.Println(b)
}

2 定义多个变量

Go 能够通过一条语句声明多个变量。

// 定义多个变量var name1, name2 type = initialvalue1, initialvalue
var s1,s2 int = 10,20
fmt.Println(s1,s2)

在有些情况下,我们可能会想要在一个语句中声明不同类型的变量。其语法如下:

var (  
    name1 = initialvalue1,
    name2 = initialvalue2
)

使用上述语法,下面的程序声明不同类型的变量。

package main

import "fmt"

func main() {
    var (
        name   = "naveen"
        age    = 29
        height int
    )
    fmt.Println("my name is", name, ", age is", age, "and height is", height)
}

3 注意

简短声明的语法要求 := 操作符的左边至少有一个变量是尚未声明的。考虑下面的程序:

package main

import "fmt"

func main() {
    a, b := 20, 30 // 声明变量a和b
    fmt.Println("a is", a, "b is", b)
    b, c := 40, 50 // b已经声明,但c尚未声明
    fmt.Println("b is", b, "c is", c)
    b, c = 80, 90 // 给已经声明的变量b和c赋新值
    fmt.Println("changed b is", b, "c is", c)
}

在上面程序中的第 8 行,由于 b 已经被声明,而 c 尚未声明,因此运行成功

但是如果我们运行下面的程序

package main

import "fmt"

func main() {  
    a, b := 20, 30 // 声明a和b
    fmt.Println("a is", a, "b is", b)
    a, b := 40, 50 // 错误,没有尚未声明的变量
}

变量也可以在运行时进行赋值。考虑下面的程序:

package main

import (  
    "fmt"
    "math"
)

func main() {  
    a, b := 145.8, 543.8
    c := math.Min(a, b)
    fmt.Println("minimum value is ", c)
}

在上面的程序中,c 的值是运行过程中计算得到的,即 a 和 b 的最小值

4 常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:

const identifier [type] = value

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明可以简写为:

const c_name1, c_name2 = value1, value2

顾名思义,常量不能再重新赋值为其他的值。因此下面的程序将不能正常工作,它将出现一个编译错误: cannot assign to a.

package main

func main() {  
    const a = 55 // 允许
    a = 89       // 不允许重新赋值
}

常量的值会在编译的时候确定。因为函数调用发生在运行时,所以不能将函数的返回值赋值给常量。

5 字符串常量

双引号中的任何值都是 Go 中的字符串常量。例如像 Hello WorldSam 等字符串在 Go 中都是常量。

无类型的字符串是常量

Hello World 这样的字符串常量没有任何类型。

const hello = "Hello World"

上面的例子,我们把 Hello World 分配给常量 hello。现在常量 hello 有类型吗?答案是没有。常量仍然没有类型。

那么, 下面的程序是如何将无类型的常量 Sam 赋值给变量 name 的呢?

package main

import (  
    "fmt"
)

func main() {  
    var name = "Sam"
    fmt.Printf("type %T value %v", name, name)

}

答案是无类型的常量有一个与它们相关联的默认类型,并且当且仅当一行代码需要时才提供它。在声明中 var name = “Sam” , name 需要一个类型,它从字符串常量 Sam 的默认类型中获取。

有没有办法创建一个带类型的常量?答案是可以的。以下代码创建一个有类型常量。

const typedhello string = "Hello World"

上面代码中, typedhello 就是一个 string 类型的常量。

Go 是一个强类型的语言,在分配过程中混合类型是不允许的。让我们通过以下程序看看这句话是什么意思。

package main

func main() {  
        var defaultName = "Sam" // 允许
        type myString string //type关键字定义新类型myString为string的别名
        var customName myString = "Sam" // 允许
        customName = defaultName // 不允许

}

在上面的代码中,我们首先创建一个变量 defaultName 并分配一个常量 Sam常量 Sam 的默认类型是 string ,所以在赋值后 defaultName 是 string 类型的。

下一行,我们将创建一个新类型 myString,它是 string 的别名。

然后我们创建一个 myString 的变量 customName 并且给他赋值一个常量 Sam 。因为常量 Sam 是无类型的,它可以分配给任何字符串变量。因此这个赋值是允许的,customName 的类型是 myString

现在,我们有一个类型为 string 的变量 defaultName 和另一个类型为 myString 的变量 customName。即使我们知道这个 myStringstring 类型的别名。Go 的类型策略不允许将一种类型的变量赋值给另一种类型的变量。因此将 defaultName 赋值给 customName 是不允许的,编译器会抛出一个错误 main.go:7:20: cannot use defaultName (type string) as type myString in assignmen

6 iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

iota 可以被用作枚举值:

const (
    a = iota
    b = iota
    c = iota
)

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

const (
    a = iota
    b
    c
)

实例:

package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}

以上实例运行结果为:

0 1 2 ha ha 100 100 7 8

分类:

技术点:

相关文章: