Go简明教程-7dayGo

本文介绍了Go语言的基础语法,包括变量、字符串、数组、切片、字典、指针、流程控制以及自定义类型。深入讲解了Go中的错误处理、结构体、方法和接口,特别是接口的隐式实现。同时,探讨了Go的并发编程特性,如sync包的使用和channel的通信。最后,提到了Go的单元测试方法。通过实例展示了Go语言在实际编程中的应用。
摘要由CSDN通过智能技术生成

Go简明教程

1 变量与内置数据类型

1.1字符串

//返回某个变量的类型
reflect.TypeOf().Kind() 
//字符串是以byte数组形式保存的,类型是uint8,占1个byte打印时需要使用string进行类型转换,否则打印的是编码值。
//一个字一般占3个字节,存文字一般使用rune数组
//转换成 []rune 类型后,字符串中的每个字符,无论占多少个字节都用 int32 来表示,因而可以正确处理中文。
1.1数组与切片

切片使用数组作为底层结构。

切片包含三个组件:容量,长度和指向底层数组的指针,切片可以随时进行扩展。

1.2字典

map 类似于 java 的 HashMap,Python的字典(dict),是一种存储键值对(Key-Value)的数据解构

赋值不存在的就是添加,如果已经存在就是修改

1.3指针

在Go语言中,一般情况参数是按值传递的,函数内部将会拷贝一份参数的副本,对参数的修改并不会影响到外部变量的值。所以如果想要从内部改变外部变量,参数使用指针。

2 流程控制(if ,for,switch)
2.1 条件语句 if else
if 条件{
    
}elif 条件{
    
}else{
    
}

//还有一种就是if带上表达式
if 表达式;条件{
    
}

2.2 switch
//switch
//和其他语言不同的地方在于,Go 语言的 switch 不需要 break,匹配到某个 case,执行完该 case 定义的行为后,默认不会继续往下执行。如果需要继续往下执行,需要使用 fallthrough
switch 条件{
    case 条件1:
    case 条件2:
    default:
}

自定义类型

//定义出来的为新类型和go原来几个类型都不一样
type 名称 类型
//判断类型的几个方法:1.下断言可以断出类型(要放在接口里面就是)
type 小王 int
const 变量名(a) 小王 = 1
var duanyan interface{}
duanyan=a
value,ok:=duanyan.(小王)可以断出类型

Go 语言中没有枚举(enum)的概念,一般可以用常量的方式来模拟枚举

在 Go 语言中,我们如果要实现枚举,则需要使用常量计数器 iota 结合 const 来实现。

我们给第一个常量赋值为 iota,在这组常量中,之后的常量就会为我们自动赋值递增。

枚举:

const(
 SexMan = iota
 SexWoman
 SexUnknown
)

func main()  {

 fmt.Println(SexMan,SexWoman,SexUnknown)
}

// 执行结果
$ go run main.go
0 1 2
2.3 for 循环

对数组(arr)、切片(slice)、字典(map)

for key,value :=range Arr {
    
}
for key,value :=range slice{
    
}
fo key,vale :=range map{
    
}
3 函数(functions)
3.1参数与返回值
//函数返回值的两种形式
func add(num1 int, num2 int) int {
    ans :=num1 + num2
    return ans
}

func add(num1 int, num2 int) (ans int) {
	ans = num1 + num2
	return
}
3.2错误处理(error handling)

如果函数实现过程中,如果出现不能处理的错误,可以返回给调用者处理。

//打开文件失败,他就会返回err给我
_,err:=os.open("filename.txt")
//errorw.New 返回自定义的错误
errors.New("error: name is null")

错误往往是可以预知的,如果出现一些不可预知的错误,如数组越界等这种情况可能会导致程序非正常退出,在Go中称为panic。

捕获异常

Go 语言也提供了类似的机制 deferrecover

我们调用recover只会捕获到抛出的第一个异常

	defer func() {
		if err := recover(); err != nil {
			fmt.Println("如果出问题", err)
		}
	}()
	for i := 0; i < 2; i++ {
		if i == 0 {
			panic("got i")
		}
		if i == 1 {
			panic("got l")

		}
4 结构体、方法和接口
4.1 结构体(struct)和方法(methods)
//随便举个例子吧
func (stu *Student) hello(person string) string {
	return fmt.Sprintf("hello %s, I am %s", person, stu.name)
}
//后面我们要调用这个方法的时候就可以直接实例一个对象、然后直接调用该方法
4.2 接口

一般而言,接口定义了一组方法的集合,接口不能被实例化,一个类型可以实现多个接口。

看看面向接口编程

package main

import "fmt"

type Person interface {
	getName() string
	getAge() int
}

type Student struct {
	name string
	age  int
}

func (stu *Student) getName() string {
	return stu.name
}

func (stu *Student) getAge() int {
	return stu.age
}

type Worker struct {
	name   string
	gender string
}

func (w *Worker) getName() string {
	return w.name
}

//声明一个接口的结构体实例
func main() {
	var p Person = &Student{
		name: "Tom",
		age:  18,
	}

	fmt.Println(p.getName(), p.getAge()) // Tom
}

//感觉有点像面向接口编程

说白了就是声明一个接口类型的变量

然后给变量实例化一个想要调用这些方法的实例(结构体)

说白了就是装备给这个人穿,穿上就有各种超能力(方法)

Go 语言中,并不需要显式地声明实现了哪一个接口,只需要直接实现该接口对应的方法即可.

那么怎么判断接口里面的函数是否实现完整呢?

var _ Person = (*Student)(nil)
var _ Person = (*Worker)(nil
  • 将空值 nil 转换为 *Student 类型,再转换为 Person 接口,如果转换失败,说明 Student 并没有实现 Person 接口的所有方法。
  • Stduent没有实现Person接口的所有方法,那么只要该方法声明在接口里面,那么给接口附上该结构体的实例就会报错。
  • Worker 同上
func main() {
	var p Person = &Student{
		name: "Tom",
		age:  18,
	}

	stu := p.(*Student) // 接口转为实例
	fmt.Println(stu.getAge())
}
4.3空接口

如果定义了一个没有任何方法的空接口,那么这个接口可以表示任意类型

5 并发编程(goroutine)
5.1 sync

Go 语言提供了 sync 和 channel 两种方式支持协程(goroutine)的并发。

  • wg.Add(1):为 wg 添加一个计数,wg.Done(),减去一个计数。
  • go download():启动新的协程并发执行 download 函数。
  • wg.Wait():等待所有的协程执行结束
5.2 channel
var ch = make(chan string, 10) // 创建大小为 10 的缓冲信道

func download(url string) {
	fmt.Println("start to download", url)
	time.Sleep(time.Second)
	ch <- url // 将 url 发送给信道
}

func main() {
	for i := 0; i < 3; i++ {
		go download("a.com/" + string(i+'0'))
	}
	for i := 0; i < 3; i++ {
		msg := <-ch // 等待信道返回消息。
		fmt.Println("finish", msg)
	}
	fmt.Println("Done!")
}
6 单元测试(unit test)
// calc_test.go
package main

import "testing"

func TestAdd(t *testing.T) {
	if ans := add(1, 2); ans != 3 {
		t.Error("add(1, 2) should be equal to 3")
	}
}
//运行 go test,将自动运行当前 package 下的所有测试用例,如果需要查看详细的信息,可以添加-v参数。
$ go test -v
=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok      example 0.040s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newbie_______

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值