[笔记]go语言基础语法

image

0.基本语法结构

package main
import "fmt"
func main(){
  fmt.Println("Hello World")
}
- 声明包
- 保留了大括号,但去掉了分号
- 和python有点像,但没有强制锁进
- 首字母大写表示public,小写表示private
- 和类c语言相似,都是从main函数开始执行

1、 变量

变量的声明和初始化

go语言的变量声明需要使用var一下,或者使用海象运算符

var x int =1 //长声明
var y,z int =1024,2048 //多重声明
p:=3 //海象运算符,短声明
//如果没有初始化,用默认值代替
const Pi=3.14 //常量,变量不可更改。声明常量需要关键字const,禁止使用海象运算符

变量类型

go是强类型语言,对于数值类型的定义域和符号分的很清,除了所有语言都有的数字类型、字符串、数组外,还有一些go独有的派生类型。

整数类型:int,int8,int32,int64,带符号和不带符号

浮点类型:Float32—单精度浮点值,Float64—双精度浮点值

布尔类型:true,false

字符串类型:string

数组类型:array

指针类型:pointer
管道类型:chan

接口类型:interface

常量

const PI =3.1415926

2 、运算符

//算术运算符
x,y :=1,2
res:=x+y //加法
res:=x-y //减法
res:=x/y //除法,取整
res:=x%y //模,取余数
res+=x //赋值运算符,类似的*=,%=

//关系运算符
res:=x==y
res:=x!=y
res:=x>y
res:=x0&&y>=0 //与门
res:=x>0||y>0 //或门
res:=!(x>y)//非门

3、 逻辑结构

判断

//判断语句
x:=1
if x>0{
  //... ...
}else{
  //... ...
}

循环


//for循环
for x:=1;x<10;x++{
  //...
}
// 省略初始化和迭代loop
x:=1
for x<10{
  //...
  x++
}

switch

//switch,注意go中没有break语句,遇到第一个匹配的case就会跳出判断,不会穿透
x:=1
switch x{
  case 1:
    //...
  case 2:
    //...
  case 3:
    //...
  default:
    //...
}

4、函数

函数结构

关键字、函数名、函数体、输入参数,返回值

//基本结构,关键字、函数名、函数体、形参、返回值
func FunName(v int) string{
  return st
}
//多个参数的输入和输出
func FunName(v1 int ,v2 int)(int,string){
  return 2,"2"
}

可变参数

// 例子:求n个整数的和
func sum(x ...int) (s int) {
    //可变参数
    for _, v := range x {
        s += v
    }
    return
}
// 也可以直接把切片扔进去作为可变参数
arr=[3]int{1,2,3}
sum(arr...) //类似于解包的操作

闭包于匿名函数

闭包给了在内部函数捕获外部函数参数的权利,匿名函数是闭包的实现方式之一,字面意思上的没有名字,直接调用的函数。

// 函数的闭包
func test14(a int, b int) int {
    func() {
        fmt.Println(a, b)
    }()
    return a + b
}

5、指针

指针,即一个值的内存地址。在go中,&表示取地址,*表示取值。

指针声明

var p1 *int
var p2 *string
// go中指针必须带类型

6、结构体

定义数据使用,类似于其他面向对象语言中的class

type Contact struct{
  Age int
  Name string
}

结构体与指针

x:=&Contact{"ronron",12}
x.name="xiaojiji"

7、方法

结构体除了声明了属性外,还能定义方法,方法即带接收器的函数。

type Contact struct{
  Name string
  Age int
}
// 方法,结构体接收器
func (c Constact) addAge1(){
  c.Age+=1 
}
// 方法,结构体指针接收器
func (c *Contact) addAge2(){
  c.Age+=1 
}


与普通函数相比,方法多了一个接收器,这个接收器可以是结构体,也可以是结构体指针。如果是结构体,那么传递的是结构体副本,修改不会影响原有的对象。如果是结构体指针,那么会影响原有的对象。

8、数组 Array

var a [3]int //定义一个长度为3的空数组
var a [3]int{1,2,3} //定义一个长度为3的数组并初始化
//数组的操作
// 索引
a[1]

数组一旦定义就无法修改大小,不方便使用,所以常用切片 slice代替

//切片定义方式一,直接从数组中切下来
a :=[5]int{1,2,3,4,5}
b:=a[1,3]

//切片定义方式二 ,使用make方法
c:=make([]int,5,10) //注意初始化长度为5,元素默认为0

//切片的遍历,和python真的相似
    for i := 0; i < len(a); i++ {
        fmt.Println(a[i])
    }
    for _, v := range a {
        fmt.Println(v)
    }

切片

go语言中的数组一旦定义就不能再改变长度,不大好用。切片是数组的高一级别的抽象,可以理解为动态数组。


// 定义一个字符串的切片,初始长度为10,容量为20
s:=make([]string 10,20)

// 切片的索引,与python相似
s[1:3]

// 

9、字典Map

//直接定义和初始化map
m := map[string]int{
        "a": 1,
        "b": 2,
    }

// 使用make进行初始化
m :=make(map[string]int)

// 添加元素
m["c"]=1024

//获取value
value,ok:=m["c"]
value,ok:=m["d"]
if ok{
  
}else{
  
}

//遍历map
for k, v := range m {
        fmt.Println(k, v)
}

//删除dict元素
delete(m,"a")

10、并发

并发是go语言提供的核心语法,相比其他语言多线程的方式,使用简单,效率更高,管理便捷。

go例程中最核心的概念是goroutine和chan

goroutine

// 任务1
func A(){
  //do some thing a
}
//任务2
func B(){
  // do some thing b
}
//关键字go 直接使用例程,类似于其他语言中开辟一个新的线程
func main(){
  go A() //处理任务A
  go B() //处理任务B
}

channel

Channel用于多个goroutine 之间进行通信,<-符合指示数据的流动方向

// 创建一个channel
ch:=make(chan int)
// 向chan中发射数据
ch <- 1
// 从chan中接受一个数据
value := <-chan
// 不用变量接收也可以
<- chan

11 错误处理

go中没有exception的概念,取而代之的是error,error在go中是一个接口

type error interface {
    Error() string //只要实现了这个方法,就算error
}

go中把‘异常’当中一个值来处理,所以并没有try catch的语法,而是通过判断error是否为nill来进行异常处理。


// 内部error的处理
func ErrorTest(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("b can not be zero")
    }
    return a / b, nil
}
// 调用
v,error:=ErrorTest(1,0)
if error !=nill{
  // 处理有错误的情况
  return
}
//...正常的处理

Panic和recove

panic用于手动抛出致命异常,直接宕机,程序线程停止。

recover 获取宕机时的信息,配合defer关键字,让程序在宕机后能继续从断点处开始运行。

你可能感兴趣的:([笔记]go语言基础语法)