Golang基础语法(2)

51 阅读4分钟

7.运算符

与Java一致,但有指针的 &,*

func main() {
    var a int = 4
    var ptr *int
    ptr = &a
    fmt.Print(*ptr)
}

8.条件语句

Go 没有三目运算符(靠)

新语句 select

select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。

select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。

如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。

9.循环语句

Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。

和 C 语言的 for 一样:

for init; condition; post { }

和 C 的 while 一样:

for condition { }

和 C 的 for(;;) 一样:

for { }

Foe-each range 循环

package main
import "fmt"func main() {
   strings := []string{"google", "runoob"}
    //i 得到下标 s得到值
   for i, s := range strings {
      fmt.Println(i, s)
   }
​
​
   numbers := [6]int{1, 2, 3, 5}
   for i,x:= range numbers {
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }  
}
package main
import "fmt"func main() {
    map1 := make(map[int]float32)
    map1[1] = 1.0
    map1[2] = 2.0
    map1[3] = 3.0
    map1[4] = 4.0
   
    // 读取 key 和 value
    for key, value := range map1 {
      fmt.Printf("key is: %d - value is: %f\n", key, value)
    }
​
    // 读取 key
    for key := range map1 {
      fmt.Printf("key is: %d\n", key)
    }
​
    // 读取 value
    for _, value := range map1 {
      fmt.Printf("value is: %f\n", value)
    }
}

10 函数

1.格式

                    //参数              //返回值类型
func function_name( [parameter list] ) [return_types] {
   函数体
}
​
可以返回多个值 (python!)
func swap(x, y string) (string, string) {
    return y, x
}
//r1 r2 此时就定义了局部变量 默认初始化0
(r1,r2 string)
func swap(x, y string) (r1 string,r2 string) {
    fmt.Print(r1) //0
    return r1,r2
}
​
//引入传递
func swap1(x, y *int) {
    var temp int
    temp = *x
    *x = *y
    *y = temp
}

返回值,执行顺序

package main
​
func add(x, y int) (z int) {
    defer func() {
        println(z) // 输出: 203
    }()
​
    z = x + y
    return z + 200 // 执行顺序: (z = z + 200) -> (call defer) -> (return)
}
​
func main() {
    println(add(1, 2)) // 输出: 203
}

11.变量作用域

  • 函数内定义的变量称为局部变量
  • 函数外定义的变量称为全局变量
  • 函数定义中的变量称为形式参数

Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑

package main
​
import "fmt"/* 声明全局变量 */
var g int = 20func main() {
   /* 声明局部变量 */
   var g int = 10
​
   fmt.Printf ("结果: g = %d\n",  g)
}

12.数组

1.格式

var name [10] int (怪难写)

var name = [5]int{1,2,3}
name :=[5]int{3,2,4} //未初始化为0

//不确定长度 用...
name :=[...]int{2}
自动检测长度  int[1] 编译错误

//下标初始化
name :=[...]float32{1:2.0,3:1.0}

func main() {
	var name = [5]int{1, 2, 3}
	for _, temp := range name {
		fmt.Print(temp) //1 2 3 0 0 
	}
}

13 指针

与c指针一致

nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。

一个指针变量通常缩写为 ptr。

空指针判断
if(ptr!=nil)

问题

func main() {
    var a *int
    *a = 100
    fmt.Println(*a)

    var b map[string]int
    b["测试"] = 100
    fmt.Println(b)
}

执行上面的代码会引发panic,为什么呢? 在Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。要分配内存,就引出来今天的new和make。 Go语言中new和make是内建的两个函数,主要用来分配内存

new

new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。举个例子

func main() {
    a := new(int)
    b := new(bool)
    fmt.Printf("%T\n", a) // *int
    fmt.Printf("%T\n", b) // *bool
    fmt.Println(*a)       // 0
    fmt.Println(*b)       // false,默认值为false
}    

所以上方出现panic的解决方案

func main(){
    var a *int;
    a=new(int)
    *a=10
}

make

make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。