Go基础:基础语法与使用

1. 变量

声明变量

var a intvar b stringvar c []float32// 这种形式一般用于回调函数,即将函数以变量的形式保存下来,在需要的时候重新调用这个函数
var d func() boolvar e struct{
           x int }

批量格式

var (
    a int
    b string
    c []float32
    d func() bool
    e struct {
        x int})

2. 指针

指针概念在Go语言中被拆分为两个核心概念:
类型指针,允许对这个指针类型的数据进行修改。传递数据使用指针,而无须拷贝数据。类型指针不能进行偏移和运算。
切片,由指向起始元素的原始指针、元素数量和容量组成。

受益于这样的约束和拆分,Go语言的指针类型变量拥有指针的高效访问,但又不会发生指针偏移,从而避免非法修改关键性数据问题。同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。

var cat int = 1var str string = "banana"
fmt.Printf("%p %p", &cat, &str)//0xc042052088 0xc0420461b0

输出值在每次运行是不同的,代表cat和str两个变量在运行时的地址。
在32位平台上,将是32位地址;64位平台上是64位地址。

// 交换函数
func swap(a, b *int) {// 取a指针的值,赋给临时变量t
   t := *a
  // 取b指针的值,赋给a指针指向的变量
  *a = *b
  // 将a指针的值赋给b指针指向的变量
    *b = t
}func main() {// 准备两个变量,赋值1和2
    x, y := 1, 2// 交换变量值
   swap(&x, &y)// 输出变量值
   fmt.Println(x, y)}

使用指针变量获取命令行的输入信息

Go语言的flag包中,定义的指令以指针类型返回

// 定义命令行参数
var mode = flag.String("mode", "", "process mode")func main() {// 解析命令行参数
	flag.Parse()// 输出命令行参数
	fmt.Println(*mode)}

$ go run flagparse.go --mode=fast

  • 参数名称:给应用输入参数时使用
    参数值的默认值:与flag所使用的函数创建变量类型对应,String对应字符串、Int对应整型、Bool对应布尔型等。
  • 参数说明:使用-help时,会出现在说明中。

Go基础:基础语法与使用_第1张图片

创建指针的另一种方法——new()函数

str := new(string)
*str = "ninja"

变量生命期——变量能够使用的代码范围

变量和栈有什么关系?

func calc(a, b int) int {var c int
	c = a * b
	var x int
	x = c * 10return x
}

栈可用于内存分配,栈的分配和回收速度非常快。Go语言默认情况下会将c和x分配在栈上,这两个变量在calc()函数退出时就不再使用,函数结束时,保存c和x的栈内存再出栈释放内存,

什么是堆?
堆在内存分配中类似于往一个房间里摆放各种家具,家具的尺寸有大有小。分配内存时,需要找一块足够装下家具的空间再摆放家具。经过反复摆放和腾空家具后,房间里的空间会变得乱七八糟,此时再往空间里摆放家具会存在虽然有足够的空间,但各空间分布在不同的区域,无法有一段连续的空间来摆放家具的问题。此时,内存分配器就需要对这些空间进行调整优化。

堆分配内存和栈分配内存相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片。

3. 字符串

长度

● ASCII字符串长度使用 len() 函数。
● Unicode字符串长度使用 utf8.RuneCountInString() 函数。

遍历字符串

● ASCII字符串遍历直接使用下标。
● Unicode字符串遍历用 for range

修改字符串

● Go语言的字符串是不可变的
● 修改字符串时,可以将字符串转换为 []byte 进行修改。
[]bytestring 可以通过强制类型转换互转

连接字符串

使用“+”对字符串进行连接操作,但在频繁拼接字符串的场景“+”性能低效。除了加号连接字符串,Go语言中也有类似于StringBuilder的机制来进行高效的字符串连接:

hammer := "吃我一锤"
sickle := "死吧"// 声明字节缓冲
var stringBuilder bytes.Buffer
// 把字符串写入缓冲
stringBuilder.WriteString(hammer)
stringBuilder.WriteString(sickle)// 将缓冲以字符串形式输出
fmt.Println(stringBuilder.String())
// bytes.Buffer是可以缓冲并可以往里面写入各种字节数组的。字符串也是一种字节数组,使用WriteString()方法进行写入。
// 将需要连接的字符串,通过调用WriteString()方法,写入stringBuilder中,然后再通过stringBuilder.String()方法将缓冲转换为字符串。

格式化

fmt.Sprintf(格式化样式,参数列表…)
● 格式化样式:字符串形式,格式化动词以%开头。
● 参数列表:多个参数以逗号分隔,个数必须与格式化样式中的个数一一对应,否则运行时会报错。

res := fmt.Sprintf("1/3=", 1.0 / 3.0) 
fmt.Printf(res)  // 1/3=0.33

Go基础:基础语法与使用_第2张图片

生成随机数

// 生成随机数
seconds := time.Now().Unix()  // 获取当前日期和时间的时间戳整数形式
rand.Seed(seconds)  // 播种随机数生成器
target := rand.Intn(100) + 1  // 每次生成的数不一样
fmt.Println(target)

从键盘读取数字

// 从键盘输入一个数字字符串并转整数
fmt.Print("Enter a number: ")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')  // 回车退出读取
fmt.Printf("input: %T %v", input, input)
if err != nil {
	log.Fatal(err)  // 报告错误并退出程序
}
input = strings.TrimSpace(input)  // 删除换行符
guess, err := strconv.Atoi(input)   // 转为整数
if err != nil {
	log.Fatal(err)
}
fmt.Printf("guess: %T %v\n", guess, guess)

你可能感兴趣的:(Go,golang)