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 = 20
func 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的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。