go基础语法之关键字

go基础语法之关键字

go语言是2007年在google公司诞生的,是基于编译、垃圾收集和并发的编程语言,专门针对多处理器系统应用程序的编程进行了优化。

go优势:

  • 自带并发支持,语言层面支持并发,实现简单。

  • 自动垃圾回收机制。

  • 可直接编译成机器码,不依赖其它库,直接运行即可部署。

  • 丰富的标准库。25个关键字,内嵌C语法支持。

  • 跨平台。

go语言25个关键字

  • package:包

  • import:导入包

  • func:用于函数定义

  • go:并发执行

  • chan:定义channel

  • if:选择结构

  • else:选择结构

  • return:返回

  • switch:选择结构

  • case:选择结构标签

  • default:用于选择结构的默认选项(switch、select)

  • select:go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。

  • for:循环语句

  • continue:跳过本次循环

  • break:break用于跳出循环

  • goto:跳转语句

  • defer:延迟执行函数

  • type:定义类型

  • var:定义变量

  • interface:定义接口

  • struct:定义结构体

  • const:定义常量

  • map:map类型

  • range:遍历slice、map等结构元素

  • fallthrough:case加上它,程序会继续执行下一条,不会判断下一条case的值

package关键字

go使用包 package 来管理定义模块,使用 import 关键字来导入go自带的包和我们自定义的包。

在项目中新建api目录,定义a.go文件

package api

import "fmt"

//函数名首字母大写表示对外开放函数,如果小写,只能当前包内调用
func A() {
   fmt.Println("A") //对外暴露函数A,打印A
}

go中函数名首字母大写表示对外开放函数,如果小写,只能当前包内调用。

main函数调用函数A,需要import中导入api包。

(go文件中存在main函数,当前package必须指定为main包)

package main

import (
 "awesomeProject/api"  //导入自定义包(自定义包需在gopath目录下)
 "fmt" //引入go标准库fmt
)

func main() {
 fmt.Println("打印A")
 
}

import也可导入匿名包, _ "包名" 导入匿名包(下划线表示匿名),即使不使用,也能正常运行。

package main

import (
  _ "aa/lib1" 
  as "aa/lib2" 起as别名
  . "aa/lib3" lib3包里面的方法都属于当前main包里面的方法
)

go关键字

go语言并发通过goroutine(轻量级线程,也叫做协程)实现,属于用户态线程。由go 运行时管理。

语法:

go 函数名(参数列表)

package main

import (
 "fmt"
 "time"
)

func main() {
 go fmt.Println("C")

 time.Sleep(3)
  
  //调用匿名函数
  go func() {
    fmt.Println("匿名函数")
 }()
}

chan关键字

go语言中为解决数据资源的同步问题,引入了通信机制——通道,为多个goroutine之间提供数据资源共享。

通道创建语法:name := make(chan type, num)

  • type指数据类型。

  • num指存放数量上限。

  • make是内置函数方法,它为切片、集合和通道分配内存和初始化。

通道创建示例:

  • ch := make(chan int)。 创建无缓冲通道,要求发送和接收操作同时准备好,否则阻塞。

  • ch := make(<-chan int)。创建只读通道(单向通道)。

  • ch := make(chan<- int)。创建只写通道(单向通道)。

  • ch := make(chan int, 10)。创建缓冲通道,容量为10。(带缓冲通道,写入时通道中数据长度不大于缓冲长度,就不会阻塞。读取带缓冲通道时,如果通道没数据,程序依然会阻塞)

在通道里面写入和读取数据需要由 <- 操作符实现:

  1. 通道变量在 <- 操作符左边,往通道写入数据;

  2. 通道变量在 <- 操作符右边,则是读取通道数据。

见如下示例代码:

func f1() {
    //带缓冲通道,写入时通道中数据长度不大于缓冲长度,就不会阻塞。读取带缓冲通道时,如果通道没数据,程序依然会阻塞
    ch := make(chan int, 1)
    ch <- 1
    go func() {
      v := <-ch
      fmt.Println("value=", v)
    }()
    
    //go语言中程序会优先执行主线程,主线程执行完毕后,程序会立即退出。
所以加了time.Sleep让主线程休眠,让匿名函数打印值。
    time.Sleep(5 * time.Second)
    fmt.Println("0")
}
func f2() {
    //通道是引用类型,需要使用 make 进行创建
    ch := make(chan int) // 创建一个整型类型的通道
    go func() {
      //阻塞接收数据
      v := <-ch
      fmt.Println(v)
    }()
    time.Sleep(5 * time.Second)
    // 尝试将0通过通道发送
    ch <- 1
    fmt.Println("0")
}

interface关键字

go语言提供了一种称为接口(interface)的数据类型,它代表一组方法的集合。

接口语法:

接口使用关键字typeinterface定义,接口方法只需设置方法名称、参数名称和数据类型、返回值的数据类型,无需在接口中编写方法的业务功能,而方法的业务功能由结构体方法实现。

type interface_name interface {
    method1(parameter) [returnType]
    method2(parameter) [returnType]
    method3(parameter) [returnType]
    ......
    methodN(parameter) [returnType]
}

接口名和方法名首字母都大写,则对外暴露。

type actions interface {
    //无参,无返回值
    a()
    //无参,有返回值
    b() (int, int)
    //有参,无返回值
    c(t1 string, t2 int)
    //有参,有返回值
    d(t1 int) (int)
}

必须实现了所有接口的方法才算是实现了这个接口。(go没有java中重写、继承。只有多态)

接口示例代码如下:

package main

import "fmt"

type actions interface {
 execute()
 setname(name string)
}

// 定义结构体
type task struct {
 name string //任务名属性
}

func (t *task) execute() {
 fmt.Println("执行任务名称:", t.name)
}

func (t *task) setname(name string) {
 t.name = name
 fmt.Println("name=", name)
}

func main() {
 f11()
}

func f11() {
 //定义接口变量
 var a actions
 //结构体实例化
 b := task{name: "sql脚本"}
 //结构体实例化变量的指针(内存地址)赋值给接口变量
 a = &b
 a.execute()
 a.setname("自动部署")
 a.execute()
 fmt.Println("打印任务名:", b.name)
}

结果输出:

执行任务名称: sql脚本
name= 自动部署
执行任务名称: 自动部署
打印任务名: 自动部署

map关键字

go语言的集合称为映射(map),是一种无序的键值对key、value的集合。

//go方法内声明变量必须使用,否则编译不通过
//:= 只能够用在函数体内声明
package main

import "fmt"

func f12() {
 //方式一:只定义
 var m1 = map[string]int{}
 m1["a"] = 1
 fmt.Printf("集合m1: %v\n", m1)
 //方式二:定义并赋值
 var m2 = map[string]int{
  "b": 2,
 }
 fmt.Printf("集合m2: %v\n", m2)
 //方式三:使用make函数定义
 m3 := make(map[string]int)
 m3["c"] = 3
 fmt.Printf("集合m3: %v\n", m3)
}

func main() {
 f12()
}

切片定义

切片是一种比较特殊的数据结构,切片可理解为动态数组,并根据切片中的元素自动调整切片长度。

定义:

  1. var array []int。声明array是一个切片,但是并没有给array分配空间。

  2. var array = []int{1, 2}。定义切片并赋值。

  3. array := make([]int, 10)。使用make()定义切片,开辟了10个空间,默认值是0。

示例代码如下:

package main

import "fmt"

func f123() {
 //定义切片并赋值
 var array = []int{1, 2}

 //使用make()定义切片
 array1 := make([]int, 10)

 fmt.Printf("%v, 内存地址:%v\n", array, &array)
 fmt.Printf("%v, 内存地址:%v\n", array1, &array1)

 //新增切片元素
 array = append(array, 3, 4, 5)
 fmt.Println("数组元素:", array)
 //截取切片元素
 //截取第二个到第三个元素(从下标1开始取,不包含下标2)
 s1 := array[1:2]
 fmt.Println(s1)
 //截取第一个到第三个元素
 s2 := array[0:2]
 fmt.Println(s2)

 for index, value := range array {
  fmt.Println("遍历数组 index= ", index, ", value=", value)
 }

 //复制切片
 slice1 := []int{1, 2, 3, 9, 0}
 slice2 := []int{4, 5, 6}
 copy(slice1, slice2)
 fmt.Println(slice1)

 //切片长度与容量(当切片长度大于容量的时候,go语言将原有容量扩大至两倍,否则元素无法新增到切片中。)
 a1 := make([]int, 3, 4)
 fmt.Printf("值%v,长度%v,容量%v\n", a1, len(a1), cap(a1))
 //第一次添加
 a1 = append(a1, 5)
 fmt.Printf("值%v,长度%v,容量%v\n", a1, len(a1), cap(a1))
 //第二次添加,容量翻倍增长,增长为8
 a1 = append(a1, 6)
 fmt.Printf("值%v,长度%v,容量%v\n", a1, len(a1), cap(a1))
}

func main() {
 f123()
}

结果:

[1 2], 内存地址:&[1 2]
[0 0 0 0 0 0 0 0 0 0], 内存地址:&[0 0 0 0 0 0 0 0 0 0]
数组元素: [1 2 3 4 5]
[2]
[1 2]
遍历数组 index=  0 , value= 1
遍历数组 index=  1 , value= 2
遍历数组 index=  2 , value= 3
遍历数组 index=  3 , value= 4
遍历数组 index=  4 , value= 5
[4 5 6 9 0]
值[0 0 0],长度3,容量4
值[0 0 0 5],长度4,容量4
值[0 0 0 5 6],长度5,容量8

参考资料

  1. 《GO语言编程从入门到实践》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值