变量

1 变量是什么

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

 

2 声明变量的基本方式

2.1 第一种方式:全定义var name type = initialvalue 

package main

import "fmt"

func main() {
    // var关键字 变量名 变量类型 = 变量值
    var age int =10   //在go中,变量定义了就必须使用,如果不使用就报错。模块导入了不使用也报错。
    fmt.Println(age)
}

2.2 第二种方式:类型推导(类型不需要写了) var name = initialvalue

如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。因此,如果变量有初始值,就可以在变量声明中省略 type

package main

import "fmt"

func main() {
    var age = 10
    var name ="zell"
    fmt.Println(age)  //打印并换行
    fmt.Print(name)   //打印不换行
    fmt.Printf("%T\n",age)  //查看变量类型,\n换行
    fmt.Printf("%T",name)   //查看变量类型,不换行
    fmt.Printf("%p",&name)  //查看内存地址
}

 2.3 第三种方式:简略声明name := initialvalue 

类型 typy var关键字都不写(必须表明是在定义变量,定义变量和使用变量是两个阶段,python中合二为一了),冒号和等号是一体

package main

import "fmt"

func main() {  
    a := 10
    var a int = 100  //重复定义,报错
    var a = 99       //重复定义,报错
    a := 99          //重复定义,报错   
    a = 99 //使用变量(赋值变量),是允许的
    b = 99 //没有定义b变量,直接使用,报错
    fmt.Println(a)
}

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

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尚未声明,我们觉得是重复定义,但goland不认为重复,因为冒号左侧,只要有一个没有定义过的变量,goland就不认为重复
    fmt.Println("b is", b, "c is", c)
    b, c = 80, 90 // 给已经声明的变量b和c赋新值
    fmt.Println("changed b is", b, "c is", c)
}

但是如果我们运行下面的程序:会抛出 no new variables on left side of := 的错误,这是因为 a 和 b 的变量已经声明过了,:= 的左边并没有尚未声明的变量。

package main

import "fmt"

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

变量也可以在运行时进行赋值。考虑下面的程序:c 的值是运行过程中计算得到的,即 a 和 b 的最小值。

package main

import (  
    "fmt"
    "math"
)

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

由于 Go 是强类型(Strongly Typed)语言,因此不允许某一类型的变量赋值为其他类型的值。下面的程序会抛出错误 cannot use "naveen" (type string) as type int in assignment,这是因为 age 本来声明为 int 类型,而我们却尝试给它赋字符串类型的值。

package main

func main() {  
    age := 29      // age是int类型
    age = "naveen" // 错误,尝试赋值一个字符串给int类型变量
}

 

3 其他变形方式 

3.1 只定义不赋值 var name type

package main

import "fmt"

func main() {
    var age int // 变量声明
    fmt.Println("my age is", age)
}

语句 var age int 声明了一个 int 类型的变量,名字为 age。我们还没有给该变量赋值。如果变量未被赋值,Go 会自动地将其初始化,赋值该变量类型的零值(Zero Value)。本例中 age 就被赋值为 0。如果你运行该程序,你会看到如下输出:

my age is 0

变量可以赋值为本类型的任何值。上一程序中的 age 可以赋值为任何整型值(Integer Value)。

如果是只定义,不赋值,只能用全定义方式var name type,类型推导方式var name报错,因为它不知道变量的类型,变量的类型在定义阶段就要确定。

3.2 声明多个变量

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

声明多个变量的语法是 var name1, name2 type = initialvalue1, initialvalue2

package main

import "fmt"

func main() {
    var width, height int = 100, 50      // 声明多个变量, 声明了type,初始化值只能为int类型
    var width, height = 100, "zell"      // 声明多个变量,类型推导方式,没有声明type,初始化值可以任意类型
    width, height :=100, "zell"          // 声明多个变量,简略方式,没有声明type,初始化值可以任意类型

    fmt.Println("width is", width, "height is", heigh)
}

3.3 声明多个变量,在一个语句中声明不同类型的变量

package main

import "fmt"

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

这里我们声明了 string 类型的 name、int 类型的 age 和 height(初值为0)

 

4 总结

1 变量类型在定义阶段就确定了,一旦确定,不允许改变,这是编译型语言的特性。
// python之所以可以改变变量类型,是因为python中一切皆对象,a=10, 在python中,其实是a指向一个内存地址,内存地址指向了10,内存地址占的比特位是固定大小,所以指向任意类型都可以。
// go语言中,就是a直接指向10,假设10属于int8类型,占8个比特位,换成字符串需要扩充比特位,是不能扩的,因此不能改变数据类型。
2 变量不可以重复定义。
3 变量要先定义再使用。

 

5 变量的作用域范围

补充:在同一个包下,函数名不能重名。在之前的.go文件的main包下,定义了test函数,因此这里用test1

package main

import "fmt"

var a int //定义全局变量a,全局有效,只要改了,就是改了

func main() {
    fmt.Println(a) //0 初始值为0
    a = 19         //赋值操作,全局修改
    fmt.Println(a) //19
    test1()        //99 调用test1,函数内部赋值操作又全局修改
    fmt.Println(a) //99
}

func test1() {
    a = 99
    fmt.Println(a)
}
package main

import "fmt"

var a int

func main() {
    var a int
    fmt.Println(a) //0
    a = 19         //局部的变量a
    fmt.Println(a) //19
    test1()        //99
    fmt.Println(a) //19 局部优先,局部定义了变量a,先用局部的
}

func test1() {
    a = 99 //全局的变量a
    fmt.Println(a)
}

 

posted @ 2022-11-12 15:54  不会钓鱼的猫  阅读(164)  评论(0编辑  收藏  举报