一、作用域
go语言中的变量的作用域都是在{ }的,在遇到{}嵌套,重新定义同一个变量时时,优先使用内部定义的变量。
package main
import "fmt"
var num = 100
func show() {
fmt.Println("function show : num : ", num)
num :=10
fmt.Println("function show : redefine num : ", num)
{
fmt.Println("function show : scope num : ", num)
num :=5
fmt.Println("function show : scope redefine num : ", num)
}
}
func main() {
fmt.Println("function main : num : ", num)
num +=100
fmt.Println("function show : add num : ", num)
show()
}
结果输入如下(程序不会报错):
function main : num : 100
function show : add num : 200
function show : num : 200
function show : redefine num : 10
function show : scope num : 10
function show : scope redefine num : 5
二、:= 和 =
最简单的讲:= 是给未定义的变量 定义类型的同时给予赋值,而 = 必须是已经声明类型的变量才能使用,比如简单的如下:
var a int
a = 100
a := 100 //报错,但非 同一个{},可以使用
b := 10
再看一个作用域和指针的 := 引起的问题:
var p *int
func foo() (*int) {
var i = 100
return &i
}
func bar() {
fmt.Println(*p)
}
func main() {
p :=foo()//这里的p和 var p 已经不是同一个地址了,因为作用域的问题
p = foo() //改成这样不会报错,因为复用了 var p
bar() // 会报错,bar用的var p;
fmt.Println(*p)
}
所以 千万注意 := 引起的 变量覆盖问题,会因为不合理使用,造成多个重复变量出现,而= 比较保险,不会产生新变量
三、字符串
cap空间
先看一下,下面代码:
s:="a"
s1:=[]byte{'a'}
fmt.Println(cap([]byte(s)))
fmt.Println(cap([]byte(s1)))
猜猜会输出什么,1 1? no!是32 1。这里解释一下,go中string底层实现是一个结构体,根据struct 大小计算规则和字节对齐,所以string最少是32。
struct String
{
byte* str;
intgo len;
};
中文字符长度
统计中英文字符,不能直接用len,具体如下:
s ="北京天安门abc!"
fmt.Println(len(s), utf8.RuneCountInString(s))
// 输出:19 10
下期讲一下衍生类型的变量