社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
Go语言25个内置关键字分析(一):https://blog.csdn.net/sinat_24568041/article/details/80904271
Go关键字按类型不同做如下区分(注:图片来自网络,若有侵权,请联系删除):
作用:用于声明map类型数据
a.Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
b.Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
c.在go语言中,map使用hash表实现,由于go是强类型语言,所以必须为map的键和值指定具体的类型,这些键或者值的类型可以是字符串、整型、指向结构体的指针等。如下:
Map的键和值都是字符串类型:
go m := make(map[string]string)
定义:可以使用内建函数 make 也可以使用 map 关键字来定义 Map:
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)
注:如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对
演示:
/*创建和使用map*/
package main
import "fmt"
func main() {
var countryCapitalMap map[string]string
/* 创建集合 */
countryCapitalMap = make(map[string]string)
/* map 插入 key-value 对,各个国家对应的首都 */
countryCapitalMap["France"] = "Paris"
countryCapitalMap["Italy"] = "Rome"
countryCapitalMap["Japan"] = "Tokyo"
countryCapitalMap["India"] = "New Delhi"
/* 使用 key 输出 map 值 */
for country := range countryCapitalMap {
fmt.Println("Capital of",country,"is",countryCapitalMap[country])
}
/* 查看元素在集合中是否存在 */
captial, ok := countryCapitalMap["United States"]
/* 如果 ok 是 true, 则存在,否则不存在 */
if(ok){
fmt.Println("Capital of United States is", captial)
}else {
fmt.Println("Capital of United States is not present")
}
}
作用:Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。如下表所示:
Range expression | 1st value | 2nd value(optional) | Notes |
array[n]E,*[n]E | index int | value E[i] |
|
slice []E | index int | value E[i] |
|
string abcd | index int | rune int | 对于string,range迭代的是Unicode而不是字节,所以返回的值是rune |
map map[k]v | keyk | value v |
|
channel | element | none |
|
演示:(演示代码摘自:http://www.runoob.com/go/go-range.html)
package main
import "fmt"
func main() {
//这是我们使用range去求一个slice的和。使用数组跟这个很类似
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
//在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
}
}
//range也可以用在map的键值对上。
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %sn", k, v)
}
//range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, c := range "go" {
fmt.Println(i, c)
}
}
作用:定义接口
定义:
/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
说明:
a. 不需要显式声明实现某个接口,只要实现相关方法就实现了接口
b. 接口也可以组合(相当于继承)
c. 可以试探是否为某个struct或interface的实例(ok pattern)
d. 可以使用匿名接口
e. 空接口可以看作是所有struct都实现了的。匿名空接口直接写成:interface{}
作用:结构体,也是符合数据类型
定义:
type typeName struct {
...
}
注:Go中的struct不仅可以将struct作为匿名字段,用type自定的类型以及内置的类型都可以作为匿名字段
作用:定义接口、定义结构体、类型定义、类型别名、类型查询
具体可参考:https://blog.csdn.net/hzwy23/article/details/79890778
作用:go 关键字用来创建 goroutine (协程),实现并发
演示:
//go 关键字放在方法调用前新建一个 goroutine 并让他执行方法体
go GetThingDone(param1, param2);
//上例的变种,新建一个匿名方法并执行
go func(param1, param2) {
}(val1, val2)
//直接新建一个 goroutine 并在 goroutine 中执行代码块
go {
//do someting...
}
作用:用于选择不同类型的通讯
参考:https://blog.csdn.net/wo198711203217/article/details/65442288
作用:用于channel通讯
演示:使用 go 关键字和 channel 实现非阻塞调用
/**
* 每次调用方法会新建一个 channel : resultChan,
* 同时新建一个 goroutine 来发起 http 请求并获取结果。
* 获取到结果之后 goroutine 会将结果写入到 resultChan。
*/
func UnblockGet(requestUrl string) chan string {
resultChan := make(chan string)
go func() {
request := httplib.Get(requestUrl)
content, err := request.String()
if err != nil {
content = "" + err.Error()
}
resultChan <- content
} ()
return resultChan
作用:用于条件判断
演示:
if age >= 0 {
fmt.Println("a")
} else {
fmt.Println("b")
}
作用:用于条件判断
说明:
Go的switch非常灵活。表达式不必是常量或整数,执行的过程从上至下,直到找到匹配项,而如果switch没有表达式,它会匹配true。这产生一种可能——使用switch编写if-else-if-else判断序列。它不会匹配失败后自动向下尝试,但是可以使用 fallthrough 使其这样做。用default可以指定当其他所有分支都不匹配的时候的行为。
演示:
package main
import "fmt"
import "time"
func main() {
i := 2
fmt.Print("write", i, " as ")
switchi {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
switchtime.Now().Weekday() {
casetime.Saturday, time.Sunday:
fmt.Println("it'sthe weekend")
default:
fmt.Println("it'sa weekday")
}
t :=time.Now()
switch{
caset.Hour() < 12:
fmt.Println("it'sbefore noon")
default:
fmt.Println("it'safter noon")
}
}
作用:用于循环控制
定义:
for init; condition; post { }
for condition { }
for { }
注:init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
参考:http://www.runoob.com/go/go-for-loop.html
执行过程:
a.先对表达式1赋初值;
b.判别赋值表达式 init 是否满足给定条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。
执行流程:
演示:
package main
import "fmt"
func main() {
var b int = 15
var a int
numbers := [6]int{1, 2, 3, 5}
/* for 循环 */
for a := 0; a < 10; a++ {
fmt.Printf("a 的值为: %dn", a)
}
for a < b {
a++
fmt.Printf("a 的值为: %dn", a)
}
for i,x:= range numbers {
fmt.Printf("第 %d 位 x 的值 = %dn", i,x)
}
}
作用:跳转语句关键字
说明:
关键字break,goto,continue,作用其实跟java语言的没啥区别,但是在java中goto是保留字段,没有任何意义,但是java中的break和continue的作用跟golang一样,可以跳出或者跳转执行指定的标签,c++中有标签,但是他的break,和continue不能说指定跳出和继续指定的标签,但是他的goto可以实现这个功能,条件成立,跳转到指定标签的执行语句中。
演示:
break关键字
LABLE1:
for {
for i := 1; i < 10; i++ {
if i == 4 {
break LABLE1 //跳出定义了标签层
}
}
}
fm.Println("break is over")
goto关键字
for {
for i := 1; i < 10; i++ {
if i == 4 {
goto LABLE2 //调整了执行位置,如果是标签是放在for语句
//之前,又是重新开始执行
}
}
}
LABLE2:
fm.Println("goto is over")
continue关键字
LABLE3:
for i := 1; i < 10; i++ {
for {
fm.Print(i)
continue LABLE3 //继续执行定义了标签层
}
}
自增符号++和自减符号--
他这个跟java语言的还是有区别的,它是作为一个语句,而不是作为一个表达式,他不能放在变量的左边,只能放在右边,譬如
a:=1
//a=a++ 或者++a,这样是错误的
只能a++,因为他是一个语句,同样道理,自减符号也是一样。
fm.Println("continue is over")
作用:在函数退出之前执行
说明:
a.在Go语言中,defer语句会在该函数结束的时候被调用,即使后面的语句运行时出现异常了defer语句仍然会被执行。
b.需要注意的是,如果defer语句中引用了参数,则该参数的值将是程序到defer这一行的时候的值,而与后面的语句没有关系。
注:https://studygolang.com/articles/3758
演示:
package main
import "fmt"
func main() {
func_b_0()
func_b_1()
func_b_2()
}
func func_b_0() {
fmt.Println("func_b_0...top")
a := 5
defer fmt.Println("a=", a)
a++
}
func func_b_1() {
fmt.Println("func_b_1...top")
a := 5
defer func() {
fmt.Println("a=", a)
}()
a++
}
func func_b_2() {
fmt.Println("func_b_2...top")
a := 5
defer func(a int) {
fmt.Println("a=", a)
}(a)
a++
}
注:由于作者是初入Go语言时间不长,文章中有些技术点表述可能不是很详细或者有问题,还望各位海涵,后期会逐渐增加,若有问题可联系作者,谢谢。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!