美文网首页
Go语言程序结构之变量

Go语言程序结构之变量

作者: WongBynn | 来源:发表于2021-10-29 13:39 被阅读0次

    初识Go语言之变量
    var声明创建一个具体类型的变量,然后给它附加一个名字,设置他的初始值,这种声明都是一个通用的形式:

    var name type = expression
    在实际的开发中,为了方便开发,我们一般不会这么写,我们会省略type或者expression,因为省略了type,编译器会由expression推断出type的值,而省略了expression,编译器会给变量自动赋值为零值,就是常见的nil。
    不同类型的零值如下表所示:

    type 零值
    int 0
    boolean false
    string ""
    slice nil
    pointer nil
    map nil
    通道 nil
    函数 nil
    零值的设计对于在实际开发中对程序员是非常有好的,因为我们不需要花费额外的精力使得一个复杂的类型的零值有意义,使得变量一开始就是一个可用的状态。这点作为Java开发者,我们深有体会,以你为一个变量如果在声明的时候没有复制,编译器就会提示报错。这点在Go里面就得到了很好的解决。

    var s string
    fmt.Println(s) // ""
    当然,我们也可以同时声明多个具有相同类型或者不同类型的变量,如下所示:

    var i,j,k int
    var b,f,s = true,4,"Hello"
    此外,变量可以通过调用返回多个值的函数进行初始化:

    var f,err = os.open(name) //os.open()返回一个文件和一个错误
    短变量声明
    在Go里面可以使用短变量声明的方式来实现变量的声明和初始化,如下:

    l := 3
    这种短小、灵活的局部变量声明方式非常受欢迎,在实际开发工作中十分常用。但是在全局变量的声明,我们依然建议您使用var来声明。

    此外对短变量声明,需要注意如下情况,至少要声明一个新变量,否则编译将无法通过

    正确的写法

    in,err := os.open(infile)
    out,err := os.open(infile)

    错误的写法,编译将无法通过

    f,err := os.open(infile)
    f,err := os.open(infile)
    指针
    指针的值是一个变量的地址,一个指针指示值保存的位置,使用指针可以间接读取或者更新变量的值。

    如果一个变量声明为var x int,表达式&x(x的地址)获取一个指向整型变量的指针,它的类型是整型指针(*int),如果值叫做p,我们就说p 指向x的地址。p 指向的变量写成 *p。

    x:=1
    p:=&x // p是整型指针,指向x
    fmt.Print(*p) //"1"
    *p := 2 // 相当于x=2
    注意:
    指针类型的变量的零值为nil,如果我们测试 p != nil,则说明p指向一个变量的地址。同时,指针也是可以比较的,两个指针当且仅当指向同一个变量或者两者相等都是nil的情况下才相等。

    var x, y int
    fmt.Println(&x == &x,&x == &y, &x == nil) // true ,false, false
    函数返回局部变量的地址是非常安全的,如下:

    var p = f()
    func f() *int{
    v := 1
    return &v
    }
    每次调用都会返回一个不同的值:

    fmt.Println(f() == f())//false
    因为指针包含变量的地址,所以传递一个指针参数给函数,能够让函数更新间接传递的变量值。

    func incr(p *int) int {
    *p++//递增p所指向的值;P本身不变
    return p
    }
    v := 1
    incr(&v) // 副作用:v现在等于2
    fmt.Println(incr(&v))//"3"(v现在是3)
    new函数
    new函数是Go内置的创建变量的函数,表达式new(T)可以创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(
    T)。

    p:=new(int)//*int类型的p,指向未命名的int变量
    fmt.Println(p)//0
    *p := 2 // 把未命名的int设置为2
    fmt.Println(2)
    注意:
    使用new创建的变量和普通取地址的普通变量没有区别,只是用new创建的变量,不需要用一个别名来专门取变量的地址。

    如下所示,两块代码其实意义是一样的
    new函数方式:

    func newInt() (*int){
    return new(int)
    }
    普通方式:

    func newInt() (*int){
    var i int
    return &i
    }
    变量的生命周期
    变量的生命周期指在程序执行过程中变量存活的时间区间。包级别的生命周期是整个程序的执行时间。相反,局部变量有一个动态的生命周期:每次执行声明语句时创建一个新的实体,变量一直存活到其不可访问为止,,这时就会被GC回收。值得注意的是,函数的参数和返回值也是局部变量。
    我们来看个例子哈:

    var global *int
    func f(){
    var x int
    x = 1
    glbal = &x
    }

    func f(){
    y := new(int)
    y = 1
    }
    这里X一定是使用堆空间的,因为在f函数返回后,x依然可以被global访问。g函数返回后,变量
    y就会变得不可访问,因此g返回后,*y就会被回收。

    如果您有任何问题,欢迎与我私信交流~

    相关文章

      网友评论

          本文标题:Go语言程序结构之变量

          本文链接:https://www.haomeiwen.com/subject/truialtx.html