1、变量定义三种方法
package main import "fmt" func main(){ var a int = 10 //第一种 fmt.Println(a) b int = 10 fmt.Println(b) //第二种 c := 10 fmt.Println(c) //第三种 }
2、数据类型
布尔型:
布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
数字类型:
整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码
字符串类型:
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
3、常量
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
定义方式两种:
//第一种 const b string = "abc" //第二种 const b = "abc"
4、函数
1)函数调用
package main import "fmt" func main() { /* 定义局部变量 */ var a int = 100 var b int = 200 var ret int /* 调用函数并返回最大值 */ ret = max(a, b) fmt.Printf( "最大值是 : %d\n", ret ) } /* 函数返回两个数的最大值 */ func max(num1, num2 int) int { /* 定义局部变量 */ var result int if (num1 > num2) { result = num1 } else { result = num2 } return result }
2)函数返回值
package main import "fmt" func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("Google", "Runoob") fmt.Println(a, b) }
3)闭包函数:
定义在函数内,对外部作用于有引用
func test(a int) (func()) { //var c int =100 b:=func() { fmt.Println(a) fmt.Println("我是闭包函数") } return b
5、if-else
package main import "fmt" func main(){ if a :=90;a>90{ fmt.Print("大于") }else if a==90{ fmt.Print(a) } }
6、包
//在同一个包下,变量,函数,都不能重复定义 //在包内定义的函数如果是小写字母开头,表示只能在包内部使用 //在外部包想使用,必须首字母大写
// 包的使用 package main import "mypackage" import "fmt" func main() { //想使用mypackage包下的test函数和test1函数 mypackage.Test1() fmt.Println("xxx") }
package mypackage import "fmt" //在同一个包下,变量,函数,都不能重复定义 //在包内定义的函数如果是小写字母开头,表示只能在包内部使用 //在外部包想使用,必须首字母大写 func Test1() { fmt.Println(test(1,2)) fmt.Println("xxxx") }
package mypackage //通常情况下,包名就是文件夹名,在同一个文件夹下,包名必须一致 func test(a,b int) int{ return a+b }
7、循环
package main import "fmt" func main(){ for i:=0;i<10;i++{ fmt.Println(i) } }
ps:for后面三个参数可以省略,当全部省略等同于其他语言的while循环
8、switch语句
switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。它可以被认为是替代多个 if else
子句的常用方式
-如果条件都不满足,走default默认
a:=11 switch a { case 1: fmt.Println("1") case 2: fmt.Println("2") case 10: fmt.Println("10") default: fmt.Println("不知道")
-fallthrough,穿透,无条件执行下一个case的内容
a:=10 switch a { case 1: fmt.Println("1") fmt.Println("xxxx") case 2: fmt.Println("2") case 10: fmt.Println("10") //穿透,无条件执行下一个case的内容 fallthrough case 11: fmt.Println("11") test5() fallthrough case 12: fmt.Println("12") }
9、数组
1)数组
数组是同一类型元素的集合,Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组。
//三种一样 var a [6]int=[6]int{1,2,3} var a =[6]int{1,2,3} a :=[6]int{1,2,3}
例:
package main import ( "fmt" ) func main() { a := [3]int{12} fmt.Println(a) }
声明一个长度为 3 的数组,但只提供了一个值 12
,剩下的 2 个元素自动赋值为 0
。这个程序将输出 [12 0 0]
2)数组是值类型:即所有函数传参都是copy传参
3)数组的长度,内置函数len
4)数组大小是类型的一部分
var a [4]int=[4]int{1,2,} var b [5]int=[5]int{1,2,} 因为数组大小不一样,所以上面不是同类型
5)与或非:&&、||、!(Go语言没有and、or和not等判断字符)
6)通过range迭代,迭代可选1-2个参数,第一个为索引,第二个为迭代的值
for i,v:=range a { //for i:=range a { fmt.Println("------",i) fmt.Println(v) }
7)多维数组
var a [7][2]int a[0][1]=100 fmt.Println(a) //[[0 100] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]
10、切片
创建 c:= [] int {6,7,8} 使用 make 创建一个切片 i := make([]int, 5, 5)
创建一个有 3 个整型元素的数组,并返回一个存储在 c 中的切片引用
ps:
1/切片自己不拥有任何数据。它只是底层数组的一种表示。对切片所做的任何修改都会反映在底层数组中
2/切片的长度是切片中的元素数。切片的容量是从创建切片索引开始的底层数组中元素数。
3/追加切片元素append
-如果添加元素大于切片容量,则容量会翻一倍
-切片类型的零值为nil,一个nil切片的长度和容量为0
4/多维切片
package main import ( "fmt" ) func main() { pls := [][]string { {"C", "C++"}, {"JavaScript"}, {"Go", "Rust"}, } for _, v1 := range pls { for _, v2 := range v1 { fmt.Printf("%s ", v2) } fmt.Printf("\n") } } // C C++ JavaScript Go Rust
11、Maps(是引用类型:当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构)
map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值。map 的零值是 nil
创建maps:
make(map[type of key]type of value)
给map添加元素:根据key赋值(xxx[key]=value)
获取map中元素:xxx[key],如果不存在,会返回零值(对应该元素类型的零值)
删除map中元素: [delete(map, key)],次函数无返回值
获取map长度:len()
12、字符串
len 统计字节数、utf8.RuneCountInString 统计字符数
遍历字符串的好方法:for range
name :="abc老家伙" for _,v:=range name{ fmt.Println(string(v)) fmt.Printf("%T",v) fmt.Println() } # 如果用简单循环,遍历出的是字节,range遍历的是字符
13、指针
记住三点: 1)& 取地址符号
2)* 放在类型旁边,表示指向这个类型的指针
3)* 放变量旁边,表示解引用(反解)
14、结构体
结构体是用户定义的类型,表示若干个字段(Field)的集合。
1)结构体的声明
type Employee struct {
Name,gender string #同类型写一行,用逗号隔开
age,salary int
}
ps:不声明type,则创建是匿名结构体
2)访问结构体字段
点好操作符 . 用于访问结构体的字段
3)匿名字段(即创建结构体时,字段可以只有类型,而没有字段名)
type Person struct {
string
int
}
4)嵌套结构体
type Address struct {
city, state string
}
type Person struct {
name string
age int
address Address
}
5)结构相等性
结构体是值类型。如果它的每一个字段都是可比较的,则该结构体也是可比较的
如果结构体出现不可比较类型,则不能比较,例如结构体含map类型
15、方法(类似python方法)
方法其实就是一个函数,在 func
这个关键字和方法名中间加入了一个特殊的接收器类型。接收器可以是结构体类型或者是非结构体类型
创建语法:func (方法)函数名(参数)(返回值){}
package main import ( "fmt" ) type Employee struct { name string salary int currency string } /* displaySalary() 方法将 Employee 做为接收器类型 */ func (e Employee) displaySalary() { fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary) } func main() { emp1 := Employee { name: "Sam Adolf", salary: 5000, currency: "$", } emp1.displaySalary() // 调用 Employee 类型的 displaySalary() 方法
值接收器方法:在内部修改值,不会影响外部的值
指针接收器方法:在内部修改至,会改变外部的值
16、接口(一系列方法的集合)
在 Go 语言中,接口就是方法签名(Method Signature)的集合。当一个类型定义了接口中的所有方法,我们称它实现了该接口。
1)定义一个鸭子类型接口
package main import "fmt" //定义一个鸭子类型接口 type Duck interface { speak() } //一个鸭子和方法 type Tduck struct { name string age int } func (a Tduck) speak(){ fmt.Println("Tduck方法",a.name) } //另一只鸭子和方法 type PDuck struct { wife,name string } func (a PDuck) speak(){ fmt.Println("PDuck",a.name) } func main(){ pD:=PDuck{name:"水鸭子"} tD:=Tduck{name:"唐老鸭"} speak(pD) speak(tD) } func speak(a Duck){ a.speak() }
2)空接口
没有包含方法的接口称为空接口。空接口表示为 interface{}
。由于空接口没有方法,因此所有类型都实现了空接口。
3)断言
//断言 func speak(p Tduck) { a:=p.(PDuck) fmt.Println(a.wife) p.speak() }
想取出类型其他的属性,需用到判断,用switch
//承接1)鸭子接口 func speak(p Duck) { switch a:=p.(type) { case PDuck: fmt.Println("唐") fmt.Println(a.wife) case Tduck: fmt.Println("普通") fmt.Println(a.name) } }
4)多接口和接口嵌套
5)接口的零值
package main import "fmt" //接口的零值 nil 接口是引用类型 type Describer interface { Describe() } func main() { var d1 Describer if d1 == nil { fmt.Println("xxxx") } }
17、异常处理
//异常处理 //defer panic recover //defer 表示延迟调用,即便程序出现严重错误,也会执行 //panic 就是python中的raise(主动抛出异常) //recover 恢复程序,继续执行
package main import "fmt" //异常处理 //defer panic recover //defer 表示延迟调用,即便程序出现严重错误,也会执行 //panic 就是python中的raise(主动抛出异常) //recover 恢复程序,继续执行 func main() { //先注册,后调用 //defer fmt.Println("xxxx") //defer fmt.Println("yyy") f1() f2() f3() } func f1() { fmt.Println("f1...") } func f2() { defer func() { if a:=recover();a!=nil{ //a 如果不等于nil,表示程序出了异常,a 就是异常信息 //a 等于nil,表示没有异常 //fmt.Println("出错了") fmt.Println(a) } //用于会被执行(相当于finally) }() fmt.Println("f2...") //var a =make([]int,3,3) //fmt.Println(a[4]) panic("你给我出去") } func f3() { fmt.Println("f3...") }
18、错误处理
package main import ( "errors" "fmt" ) //错误 func circleArea(radius int) (int, error) { if radius < 0 { return 0, errors.New("错误信息") //panic("xddd") } return 100, nil } func main() { a,_:=circleArea(-10) if err!=nil{ fmt.Println(err) } //fmt.Println(err) fmt.Println(a) _,err:=fmt.Println() if err!=nil{ fmt.Println("打印出错") } }