Golang学习-变量、指针

命名规则

Go语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线。大写字母和小写字母是不同的:heapSort和Heapsort是两个不同的名字。 此外首字母是否大小写还影响到该函数、变量、常量的访问权限,命名以小写开头只能被同包访问。

根据Go的SDK包的命名风格习惯可以看出文件名以下划线 _ 分割多个单词;函数,变量常量等使用驼峰命名规则。

声明

声明语句定义了程序的各种实体对象以及部分或全部的属性。Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明。下面列举变量、常量和函数的声明,类型的声明后面再详细说明。

package main

import (
	"fmt"
	"strconv"
)

const name = "dskxvos"

func main() {
	var age = 32
	fmt.Println(welcome(name, age))

}

func welcome(name string, age int) (welcomeStatement string) {
	return "欢迎访问我的博客,我是" + name + ",今年" + strconv.Itoa(age) + "岁"
}

以上代码 我们定义了一个名为name的常量,一个名为age的变量,除了运行的main函数之外,我们还定义了一个 名为welcome的函数,他接受string,int两个类型的参数,返回一个string的结果。

变量 & 常量

变量的常用声明方式有以下几种

	//var 变量名 数据类型 = expression
	//数据类型 和 expression 可以省略一个  因为省略数据类型时 会根据 expression推导其类型
	var a float64 = 3.1415926 * 5
	var b  = 3.1415926 * 5
	//简短变量声明  变量名 := expression 一般运用在局部变量的声明和初始化
	c := a * a
	//多变量声明只应该用在代码可读性高的地方 如for循环中
	i, j := 12, 15
	
	//返回值声明
	//返回值声明时 如果变量已经存在,则会重新给该变量复制,
	//但是返回值声明要求至少要声明一个新的变量,否则应该直接使用赋值 而不是声明 以下被注释的函数则为错误示范
	f, err := os.Open("aaa")
	//f 和err 变量都已经存在了,没有声明新的变量,不能使用 := 声明
	//f, err := os.Open("aaa")
	//虽然err变量已经存在了,但是定义了新的变量file 所以这段下面这段代码是可以通过编译的。
	file, err := os.Open("aaaaaaa")

以上就是变量的基本定义方式,在第一个代码示例中,我们通过 const 声明了一个常量 ,常量的声明和变量类似 但是常量必须以 const 声明 并且不能使用** := **简短声明即可

指针

一个指针的值是另一个变量的地址。一个指针对应变量在内存中的存储位置。并不是每一个值都会有一个内存地址,但是对于每一个变量必然有对应的内存地址。通过指针,我们可以直接读或更新对应变量的值,而不需要知道该变量的名字(如果变量有名字的话),关于指针的概念就不在此过多赘述了。在Go中,我们通过 [&变量名] 得到某个变量的指针,通过 [*指针] 得到其内存中的值,代码示例如下

package main

import (
	"fmt"
)


func main() {

	var x = 1
	var p *int = &x // &变量名 获取x的指针,其指针类型为 类型为 *int
	fmt.Println(p)
	fmt.Println(*p) //*指针类型 得到其内存中的值
	*p = 2          //重写内存中的值
	fmt.Println(x)

	var a, b int
	fmt.Println(&a == &a, &a == &b, a, &a == nil)

	fmt.Println(f() == f())

}

func f() *int {
	num := 1
	return &num
}

关于以上代码的执行结果

// fmt.Println(p) 此时输出的是变量 x 的指针,即x的内存地址
0xc00001a098
//fmt.Println(*p) 通过*指针类型,得到其内存中的值,即声明x时赋值的1
1                 
// *p = 2   修改指针p内存中的值为2
// fmt.Println(x)  此时,x的指针p指向的内存中的值被修改为2
2
//    var a, b int 声明 a b两个变量
// fmt.Println(&a == &a, &a == &b, a, &a == nil) 
//1. a的指针和a的指针肯定是相同的 
//2. a的值和b的值虽然是一样的,但是他们在内存中指向的是两个内存地址 所以他们的指针是不相同的
//3. 打印a的值,默认值为0
//4. a的指针不为空
true false 0 false
//通过f()函数返回两个 *int类型的指针,因为每次执行都会重新声明一个num的变量,所以他们的指针也是不相同的
false   

new函数

另一个创建变量的方法是调用内建的new函数。表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T。

	// 通过new()返回 *int的指针
	n := new(int)
	//此时打印的是指针 即内存地址
	fmt.Println(n)
	//此时打印指针中内存的值为0
	fmt.Println(*n)
	//在新建一个 零值的匿名变量,返回其指针
	m := new(int)
	//此时打印 false ,虽然n和m内存中的值都为0,但是n和m存储的数据在内存中是不同的位置,即内存地址不同(指针)所以为false
	fmt.Println(m == p)

new函数使用通常相对比较少,因为对于结构体来说,直接用字面量语法创建新变量的方法会更灵活,后面会详细说明。

变量的声明周期

变量的生命周期指的是在程序运行期间变量有效存在的时间段。对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。而相比之下,局部变量的生命周期则是动态的:每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值