Go 语言学习手札 ━━ 变量与常量

一、 变量的声明、初始化与赋值

单个变量的声明和赋值

  • 变量的声明格式:var <变量名称> [变量类型],如: var a int
  • 变量的赋值格式:<变量名称> = <值|表达式|函数>,如:a = 1a = b + ca = len(a)
  • 声明和赋值同时进行:var <变量名称> [变量类型] = <值|表达式|函数>,如:var a int = 1var b = 3
  • 分组声明格式:
var (
    a int
    b float32 = 1
    c string
    d bool = true
)
  • 同一行声明多个变量和赋值:var <变量 a>, <变量 b>, <变量 c> [变量类型] = <变量 a 的值>, <变量 b 的值>, <变量 c 的值>,或者 <变量 a>, <变量 b> := <变量 a 的值>, <变量 b 的值>
  • 全局变量的声明必须使用 var 关键字,局部变量则可以省略
  • 声明了变量却没给变量赋值,那么变量默认为零值(零值就是变量没有做初始化时系统默认设置的值)
  • 在同一个代码块中,不允许多次对相同名称的变量使用初始化声明,但是可对相同变量名称的变量进行赋值
  • 在一个变量被声明之前使用它,将会得到一个编译错误
  • 在同一个代码块中,不允许存在声明了确未使用的变量,否则将会得到一个编译错误
  • 特殊变量:_,在 Go 语言中,如变量的名称为 _,表示接下来的程序中不需要在使用这个值

类型零值

数值类型0
布尔类型false
字符串类型“” (空字符串)

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值。当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝。可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)。值类型的变量的值存储在栈中。

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同。

更复杂的数据通常会需要使用多个值,这些数据一般使用引用类型保存。
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个值所在的位置。这个内存地址为称之为指针,这个指针实际上也被存在另外的某一个值中。

同一个引用类型的指针指向的多个值可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些值分散存放在内存中,每个值都指示了下一个值所在的内存地址。

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。 如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,r2 也会受到影响。

类型转换

  • Go 语言中不存在隐式转换,类型转换必须是显示的
  • 类型转换只能发生在两种兼容类型之间
  • 兼容类型之间进行转换时可能丢失精度
  • 类型转换格式:<变量名称> [:] = <目标类型>(<需要转换的变量>)

二、变量可见性规则

  • 大写字母开头的变量是可导出的,也就是其他包可以读取的,是公共变量
  • 小写字母开头的就是不可导出的,是私有变量

例:test.go

package test

var TestPublic = "Public variable"
var testPrivate = "Private variable"

main.go

package main

import (
    "fmt"
    "test"
)

func main() {
    fmt.Print(test.TestPublic) // 输出 Public variable
    fmt.Print(test.testPrivate) // 报错
}

三、常量的声明及 iota 的使用

常量的定义形式和常量的类型范围

常量的定义从形式上课分为显示和隐式

  • 显示:const identifier [type] = value
  • 隐式:const identifier = value(通常叫无类型常量)

常量中的数据类型只可以是布尔型、数值类型(整数类型、浮点类型和复数)以及字符串类型,另外定义常量时可以使用内置表达式返回的值作为常量的值(如:len()),但是自己定义的值不允许用作为定义常量的值

特殊常量 iota 的使用

  • 特殊常量,可以认为是一个可以被编译器修改的常量。
  • iota 在 const 关键字出现时将被重置为 0(const 内部的第一行之前)
  • 在 const 中,每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)
  • iota 常见使用法
    • 跳值使用法
    • 插队使用法
    • 表达式隐式使用法
    • 单行使用法

例:

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)
}
标签:

About: Mr.zhang

成谜于写 bug 无法自拔~


发表评论

邮箱地址不会被公开。 必填项已用*标注