教程中没有的goLang基础中深层次问题
1. 你不知道的常量和变量的另一个区别
我们知道常量只能做一次赋值。但是还有很多人不知到的是,常量并不会分配到内存中去。也就是说,在goLang编程中,是取不到常量的地址的。 但我们可以变量的地址。
2. 函数的返回类型定义变量和不定义变量到底是不是一样
定义函数返回类型,有两种方式,例如 :
//第一种:直接给出返回类型
func method() int,error{}
//第二种:在返回类型上定义变量名
func method() a int,e error{}
看似这两种方式没什么影响,但是当我们在函数内使用defer
关键字的时候,就会发现返回值会受影响。
例如下面的两个代码:
func deferM1(i int) int{
t:=i
defer func(){
t+=3
}()
return t
}//返回结果t
func deferM2(i int) (t int){
t=i
defer func(){
t+=3
}()
return t
}//返回结果3+i
3. 指针变量的初始值
定义指针变量时,如果在没有赋值的情况下,它的初始值的确是nil
,这个一点问题没有。但是如果把这个指针变量的值返回给了一个接口类型,这时候会是啥呢。很神奇,它是一个被包装的nil
是这样的<nil>
,具体代码如下:
type People interface {
Show()
}
type Student struct {
name string
age int
addr string
}
func (str Student)Show(){}
func live() People {
var str *Student
return str
}//这个方法返回的是<nil>
func live() *Student {//如果方法是这样定义的话
var str *Student
return str
}//神奇的事情发生了,返回的值是nil
4. for index,val:=range xxx{} 语句值得注意的问题
当我们使用for range 遍历集合的时候,自然的认为,val的到的是集合里面的元素地址。如果这样认为的同学,就错了。其实index和val这两个变量,在内存中的位置是不变的。每一次遍历,都会把集中的值copy到这两个变量中。取下一个元素时,会覆盖当前已存的值。如下代码
type Student struct {
name string
age int
addr string
}
func show() {
strm := make(map[string]*Student)
strs:=[]Student{
{"zhangsan",14,"四川成都"},
{"lisi",16,"湖北武汉"},
{"xiaoming",18,"四川自贡"}}
for _,str:=range strs{//strm的值都是同一个地址值,也就是str变量的地址
strm[str.name]=&str
}
fmt.Println(strm,strs)
for key,val:=range strm{
fmt.Println(key,val.name)
}
fmt.Println("=============================================")
for i:=0;i<len(strs);i++{//使用这个方法才能正确获取每个元素的地址
strm[strs[i].name]=&strs[i]
}
fmt.Println(strm,strs)
}