Go语言的变量

变量声明和初始化的三种方法

1. 变量标识以及类型

var A int = 3

var A int
A = 3
👆如果使用这种方法,单纯定义A,没有初始化,A默认值为零值,不同类型零值不同

  • 数值类型(包括complex64/128)为 0
  • 布尔类型为 false
  • 字符串为 “”(空字符串)

以下几种类型为 nil:

  • var a *int
  • var a []int
  • var a map[string] int
  • var a chan int
  • var a func(string) int
  • var a error // error 是接口
package main

import "fmt"

func main() {
    var i int
    var f float64
    var b bool
    var s string
    fmt.Printf("%v %v %v %q\n", i, f, b, s)
}
输出结果是:

0 0 false ""

数值类型:

int 和 uint 有符号和无符号整数

有rune,int8,int16,int32,int64和byte,uint8,uint16,uint32,uint64
一字节–二字节–四字节–八字节
rune是int32别称,byte和uint8的别称
不同类型的变量之间不允许相互赋值或操作,不然会引起编译器报错

float 浮点数

包括float32和float64 默认float64 —>八字节

complex 复数

complex64和complex128
32位实数+32位虚数与64位实数+64位虚数
例如:var c complex64 = 5 + 5i

字符串

Go语言中字符串都是采用UTF-8字符集编码,字符串是由一对双引号""或反括号``括起来定义的
注意,单引号不能表示字符串,这点与Python不同

Go语言中字符串是不可以改变的,这点和python相同,例如以下代码会报错

var s string = "hello"
s[0] = 'c'

需要转换成字符数组之后修改

s := "hello"
c := []byte(s)   //将s转换为[]byte类型
c[0] = 'c'
s2 := string(c) //再转回string类型

反单引号`包裹的字符串是Raw字符串,代码中的形式就是打印的形式,没有字符转义
m := `hello
world!`

错误类型

Go语言内置error类型,用来处理错误信息,Go语言的package里有专门一个包errors来处理错误

常量

常量就是在编译阶段就确定下来的值,而程序在运行时无法改变该值。
Go语言中,常量可定义为数值,布尔值或字符串等类型
语法如下

const constName = value
const Pi float32 = 3.1415926
iota枚举

Go语言里有一个关键字iota,用来声明enum的时候采用,默认开始值为0,每调用一次+1

const(
	x = iota // x = 0
	y = iota // y = 1
	z        // z = 2
	//当常量声明省略值时,会默认和之前一个值字面相同,这里隐式说明z=iota,如果是第一个值省略,那就是零值
)
array数组

定义方式var arr [n]type
n是长度,type是类型
也可以使用另一种:=方式来声明
a := [3]int{1,2,3}
c := [...]int{4,5,6} 忽略长度,自动计算

Go数组之间的赋值是值传递,也就是说函数传入数组不会改变原数组的值,这点和C++不同
如果要使用指针,那么就要用到Slice

slice 动态数组

slice声明和array一样,但是不需要长度
var slice []type
slice := []byte {'a','b','c'}
slice可以从一个数组中得到,得到的是这个数组切片的引用
例如
var arr = [10]int{1,2,3,4,5,6,7,8,9,10}
var slice = arr[:5]
这样slice就是arr切片 的引用,改变slice也会改变数组

  • len函数可以获取slice长度
  • cap可以获取slice最大值 (从数组导出)
  • append可以向slice添加一个或多个元素,然后返回一个和slice一样类型的slice
  • copy函数copy从源slice的src复制元素到目标dst

append函数会改变slice所引用数组的内容,从而影响到引用同一数组的slice
append函数如果超出了原有数组的大小,那么新slice会迁移到新的地址,此时对此slice进行坐标修改操作不会影响到原来的数组以及原来数组引出的slice。

map 字典

map[keyType]valueType
如果使用var mapname map[keyType]valueType声明字典,此时字典初始化为nil,不能进行赋值操作
需要make后才能赋键值对

var numbers map[string]int
numbers = make(map[string]int)

这样有些复杂,第一步的声明看起来有些冗余,因此一般使用以下方法

numbers := make(map[string]int)

之后可以进行键值对的赋值

numbers["one"] = 1

也可以声明时就赋值

var numbers = map[string]int{"one":1, "two":2}
// 如果有初值,那么引用numbers就不会是nil,此时无需再Make,以后可以直接键值对赋值
numbers["three"] = 3

2. 变量标识,自动类型推导

var A = 3
这时候必须初始化,根据初始化值自动推导类型

3. 直接声明 :=

A := 3
A为变量,此时相当于声明以及初始化了一个变量,同样需要初始化
注意 使用:=前无需再用Var声明,否则编译器会报错

总结一下三种类型

var A int = 3
-----------> 如果初始化,编译器可以通过3推断出A为int类型,可以省略int
var A = 3
-----------> var标识符可以进一步省略,通过:=标识符代表同样的意思
A := 3

多变量声明

使用逗号,同C++,JAVA,也可以使用因式分解

var name1,name2,name3 type = value1,value2,value3 

var name1,name2,name3 = value1,value2,value3

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
name1,name2,name3 := value1,value2,value3

// 这种因式分解关键字的写法一般用于声明全局变量
var (
    vname1 v_type1
    vname2 v_type2
)

注意 go语言所有声明的变量都必须被使用,除了全局变量可以声明但不使用

值类型和引用类型

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值
在这里插入图片描述
这里i指向的就是这个地址里的内容,随着里面的内容改变i的值也会改变
值类型变量的值存储在堆中。
和C++相同,go可以通过&取得变量地址
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。

在这里插入图片描述

这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中。

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

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。

如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

volcanical

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值