好的网站模板企业文化培训
目录
1 变量
1.1 声明变量
1.2 初始化
1.3 匿名变量
2 数据类型
2.1 常用类型
2.2 数据类型转换
3 常量
4 fmt
4.1 输出
4.2 打印格式
4.3 输入
5 流程控制
5.1 IF
5.2 Switch
5.3 FOR
6 函数
6.1 普通函数
6.2 匿名函数
6.3 可变参数
6.4 defer
7 MAP
8 数组和切片
8.1 数组
8.2 切片
1 变量
变量是计算机语言中储存数据的基本单元,变量指定了某存储单元(Memory Location)的名称,该存储单元会存储特定类型的值。
变量又分为局部变量和全局变量。
- 局部变量,是定义在大括号({})内部的变量,大括号的内部也是局部变量的作用域。
- 全局变量,是定义在函数和大括号({})外部的变量。
1.1 声明变量
变量声明以关键字var
开头,变量类型放在变量的后面,行尾无需分号。
var name type
var 变量名 变量类型
声明多个变量:
var (a stringb intc bool)var (name = "golang"age = 20height int)var width, height int = 100, 50
1.2 初始化
如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。因此,如果变量有初始值,就可以在变量声明中省略 type
。
var a int = 10 //标准
var b = 10 //省略 type,自动推断类型
name, age := "golang", 29 //简短声明, := 操作符的左边至少有一个变量是尚未声明的
1.3 匿名变量
在使用多重赋值时,尤其是当Go语言的函数返回多个值,而想要忽略某个值时,那么就可以使用匿名变量,即下画线“_”替换即可,也称作空白符。
x, _ := foo()_, y := foo()
匿名变量既不占用命名空间,也不会分配内存。
注意:
GOlang的全局变量只声明不使用会报错。
处理方法:关闭golang 的 variable declared but not used
2 数据类型
在Go语言中,有以下几种数据类型。
基本数据类型(原生数据类型):整型、浮点型、复数型、布尔型、字符串、字符(byte、rune)。
复合数据类型(派生数据类型):数组(array)、切片(slice)、映射(map)、函数(function)、结构体(struct)、通道(channel)、接口(interface)、指针(pointer)。
2.1 常用类型
1)整型
2)浮点型
3)字符
byte 是 uint8 的别名。
rune 是 int32 的别名。
4)字符串
字符串是字节的集合。双引号书写字符串被称为字符串字面量(string literal),这种字面量不能跨行。Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。
s1 := "hello"
多行字符串需要使用反引号“`”,多用于内嵌源码和内嵌数据。
s1 := `第一行第二行第三行`
转义字符
常用方法
5)复数类型
complex64:实部和虚部都是 float32 类型的的复数。
complex128:实部和虚部都是 float64 类型的的复数。
内建函数complex用于创建一个包含实部和虚部的复数。complex 函数的定义如下:
func complex(r, i FloatType) ComplexType也可以使用简短语法:
c := 6 + 7i
2.2 数据类型转换
Go 有着非常严格的强类型特征。Go 没有自动类型转换。
必须采用数据类型前置加括号的方式进行强制类型转换。
3 常量
常量中的数据类型只可以是布尔型、数字型(整型、浮点型和复数型)和字符串。常量的定义格式如下:
const 标识符 [类型] = 值const a int = 10
a = 20 // 不允许对常量重新赋值
const b = math.Sqrt(4) // 常量的值会在编译的时候确定,所以不允许将函数的返回值赋值给常量
Go语言现阶段没有提供枚举,可以使用常量组模拟枚举。
import "fmt"const(status = 0female = 2
)fun main(){fmt.println(status,female)
}
iota
iota,特殊常量值,是一个系统定义的可以被编译器修改的常量值。
iota只能被用在常量的赋值中,在每一个const关键字出现时,被重置为0,然后每出现一个常量,iota所代表的数值会自动增加1。iota可以理解成常量组中常量的计数器。
const (n1 = iota //0n2 //1n3 //2n4 //3)
4 fmt
4.1 输出
fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。
1) Print
Print系列函数会将内容输出到系统的标准输出,区别在于Print函数直接输出内容,Printf函数支持格式化输出字符串,Println函数会在输出内容的结尾添加一个换行符。
func main() {fmt.Print("在终端打印该信息。")name := "枯藤"fmt.Printf("我是:%s\n", name)fmt.Println("在终端打印单独一行显示")
}
2) Fprint
Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。
// 向标准输出写入内容
fmt.Fprintln(os.Stdout, "向标准输出写入内容")
fileObj, err := os.OpenFile("./xx.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {fmt.Println("打开文件出错,err:", err)return
}
name := "枯藤"
// 向打开的文件句柄中写入内容
fmt.Fprintf(fileObj, "往文件中写如信息:%s", name)
3)Sprint
Sprint系列函数会把传入的数据生成并返回一个字符串。
s1 := fmt.Sprint("枯藤")
s2 := fmt.Sprintf("name:%s,age:%d", name, age)
s3 := fmt.Sprintln("枯藤")
4) Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。
err := fmt.Errorf("这是一个错误")
4.2 打印格式
通用打印格式
BOOL打印格式
整型打印格式
浮点型打印格式
字符串和字符数组打印格式
指针
4.3 输入
1) fmt
func Scan(a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)
2) bufio.NewReader
func bufioDemo() {reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象fmt.Print("请输入内容:")text, _ := reader.ReadString('\n') // 读到换行text = strings.TrimSpace(text)fmt.Printf("%#v\n", text)
}
5 流程控制
5.1 IF
if 是条件语句,如果 condition
为真,则执行 {
和 }
之间的代码。
if condition { //...
}
if condition { //...
} else if condition {//...
} else {//...
}
if
还有另外一种形式,它包含一个 statement
可选语句部分,该组件在条件判断之前运行。
if statement; condition { //...
}
if num := 10; num % 2 == 0 { //checks if number is evenfmt.Println(num,"is even") } else {fmt.Println(num,"is odd")}
注意:else
语句应该在 if
语句的大括号 }
之后的同一行中。如果不是,编译器会不通过。
5.2 Switch
switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。
switch var1 {case val1:...case val2:...default:...
}
定义多个表达式:
letter := "i"switch letter {case "a", "e", "i", "o", "u": // 一个选项多个表达式fmt.Println("vowel")default:fmt.Println("not a vowel")}
switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。
switch x.(type){case type:statement(s) case type:statement(s)default: /* 可选 */statement(s)
}
Fallthrough 语句:
在 Go 中,每执行完一个 case 后,会从 switch 语句中跳出来,不再做后续 case 的判断和执行。使用 fallthrough
语句可以在已经执行完成的 case 之后,把控制权转移到下一个 case 的执行代码中。
func main() {num := 75//表达式是可选的,可以被省略switch {case num < 50:fmt.Printf("%d is lesser than 50\n", num)fallthroughcase num < 100:fmt.Printf("%d is lesser than 100\n", num)fallthroughcase num < 200:fmt.Printf("%d is lesser than 200", num)}
}
5.3 FOR
for
是 Go 语言唯一的循环语句。Go 语言中并没有其他语言比如 C 语言中的 while
和 do while
循环。
形式1 :for init; condition; post { }
形式2 :for condition { }
形式3 :for { }init:初始化部门;
condition: 条件;
post: 控制变量增量或减量。
案例:
for i := 1; i <= 10; i++ {fmt.Printf(" %d",i)}
break 语句用于在完成正常执行之前突然终止 for 循环
for i := 1; i <= 10; i++ {if i > 5 {break //loop is terminated if i > 5}fmt.Printf("%d ", i)}
continue 语句用来跳出 for 循环中当前循环
for i := 1; i <= 10; i++ {if i%2 == 0 {continue}fmt.Printf("%d ", i)}
6 函数
6.1 普通函数
函数声明通用语法如下:
func functionname(parametername type) returntype { // 函数体(具体实现的功能)
}func functionname() { // 注: 表示这个函数不需要输入参数,且没有返回值
}
函数使用示例:
func calculatePrice(price int, num int) int { var totalPrice = price * num // 商品总价 = 商品单价 * 数量return totalPrice // 返回总价
}//如果有连续若干个参数,它们的类型一致,那么我们无须一一罗列,只需在最后一个参数后添加该类型。
func calculatePrice2(price , num int) int { var totalPrice = price * num // 商品总价 = 商品单价 * 数量return totalPrice // 返回总价
}func main() { price, num := 90, 6 // 定义 price 和 num,默认类型为 inttotalPrice := calculatePrice(price, num)fmt.Println("Total price is", totalPrice) // 打印到控制台上
}
多返回值:
Go 语言支持一个函数可以有多个返回值。我们来写个以矩形的长和宽为输入参数,计算并返回矩形面积和周长的函数 rectProps。
func rectProps(length, width float64)(float64, float64) { var area = length * widthvar perimeter = (length + width) * 2return area, perimeter //同时返回两个值,面积和周长
}func main() { area, perimeter := rectProps(10.8, 5.6)fmt.Printf("Area %f Perimeter %f", area, perimeter)
}
命名返回值:
//从函数中可以返回一个命名值,函数中的 return 语句没有显式返回任何值。由于 area 和 perimeter 在函数声明中指定为返回值, 因此当遇到 return 语句时, 它们将自动从函数返回。
func rectProps(length, width float64)(area, perimeter float64) { area = length * widthperimeter = (length + width) * 2return
6.2 匿名函数
匿名函数没有函数名,只有函数体,函数可以作为一种类型被赋值给变量,匿名函数也往往以变量方式被传递。
1)定义匿名函数的时候就可以直接使用(仅使用一次)
func main() {res := func(length, width float64)float64{return length*width}(10.6,20.8)
}
2)可以将匿名函数赋值给变量,再通过该变量来调用匿名函数
func main() { res := func(length, width float64)float64{return length*width}res1 := res(2.4,6.2)fmt.Println(res1)
}
3)匿名函数作为返回值
func caculate() func(float64,float64){area := func(length,width float64 ){println(length*width)}return area
}
6.3 可变参数
如果函数最后一个参数被记作 ...T
,这时函数可以接受任意个 T
类型参数作为最后一个参数。
func find(num int, nums ...int) {fmt.Printf("type of nums is %T\n", nums)found := falsefor i, v := range nums {if v == num {fmt.Println(num, "found at index", i, "in", nums)found = true}}if !found {fmt.Println(num, "not found in ", nums)}fmt.Printf("\n")
}func main() {find(89, 89, 90, 95)
}
6.4 defer
含有 defer 语句的函数,会在该函数将要返回之前,调用另一个函数。
func finished() { fmt.Println("Finished finding largest")
}func largest(nums []int) { defer finished()fmt.Println("Started finding largest")max := nums[0]for _, v := range nums {if v > max {max = v}}fmt.Println("Largest number in", nums, "is", max)
}func main() { nums := []int{78, 109, 2, 563, 300}largest(nums)
}
在 largest() 函数将要返回之前,会调用 finished() 函数。
defer也可以用来延迟方法:
func printA(a int) { fmt.Println("value of a in deferred function", a)
}
func main() { a := 5defer printA(a)a = 10fmt.Println("value of a before deferred function call", a)}
当一个函数内多次调用 defer 时,Go 会把 defer 调用放入到一个栈中,随后按照后进先出(Last In First Out, LIFO)的顺序执行。
7 MAP
Go 语言提供了内置类型 map,它将值(value)与键(key)关联起来,可以使用相应的键检索值。
1)创建MAP
var 变量名 map[KeyType]ValueType //使用var关键字定义map
变量名 := make(map[string]int) //通过向
make
函数传入键和值的类型
var person map[string]intif person == nil {fmt.Println("map is nil. Going to make one.")person = make(map[string]int)}
2)添加元素
var country = map[string]string{"China": "Beijing","Italy": "Rome",
}
country["Japan"] = "XRIBen"
3)检索map值
value, ok := map[key]
func main() {var country = map[string]string{"China": "Beijing","Italy": "Rome",}country["Japan"] = "XRIBen"newCon := "Italy"value, ok := country[newCon]if ok == true {fmt.Println("Capatoal of", newCon, "is", value)} else {fmt.Println(newCon,"not found")}
}
for range循环遍历
(1)、key 、value都遍历for k, v := range countryMap {fmt.Println("国家", k, "首都", v)}
(2)、只展示valuefor _, v := range countryMap {fmt.Println("国家", "首都", v)}
(3)、只展示keyfor k := range countryMap {fmt.Println("国家", k , "首都", countryMap[k])}
4)删除元素
删除 map 中 key 的语法是 delete(map, key)。这个函数没有返回值。
delete(country, "Japan")
5)其他
len(personSalary) 函数获取map 的长度。
map 是引用类型。当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。
map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil。
8 数组和切片
8.1 数组
数组是同一类型元素的集合。一个数组的表示形式为 [n]T。n 表示数组中元素的数量,T 代表每个元素的类型。元素的数量 n 也是该类型的一部分。
1)声明数组
var a [3]int //int array with length 3
a[0] = 12 // array index starts at 0
a := [3]int{12, 78, 50} // short hand declaration to create array
a := [...]int{12, 78, 50} // ... makes the compiler determine the length
Go 中的数组是值类型而不是引用类型。这意味着当数组赋值给一个新的变量时,该变量会得到一个原始数组的一个副本。如果对新变量进行更改,则不会影响原始数组。
2)遍历数组
a := [...]float64{67.7, 89.8, 21, 78}
for i := 0; i < len(a); i++ { fmt.Printf("%d is %.2f\n", i, a[i])
}for i, v := range a {fmt.Printf("%d is %.2f\n", i, v)
}
3)多维数组
func printarray(a [3][2]string) {for _, v1 := range a {for _, v2 := range v1 {fmt.Printf("%s ", v2)}fmt.Printf("\n")}
}func main() {a := [3][2]string{{"lion", "tiger"},{"cat", "dog"},{"pigeon", "peacock"}, }printarray(a)
}
8.2 切片
1)声明
切片由 []T 表示,没有元素数量。
a := [5]int{76, 77, 78, 79, 80}
var b []int = a[1:4] // creates a slice from a[1] to a[3]var b []int = arr[start:end] var b []int = arr[:end] var b []int = arr[start:] var b []int = arr[:] var b = arr[:len(arr)-1] //去掉切片的最后一个元素c := []int{6, 7, 8} // creates and array and returns a slice reference
2)修改切片
切片自己不拥有任何数据。它只是底层数组的一种表示。对切片所做的任何修改都会反映在底层数组中。
func main() {darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}dslice := darr[2:5]fmt.Println("array before", darr)for i := range dslice {dslice[i]++}fmt.Println("array after", darr)
}
3)make创建切片
func make([]T,len,cap)[]T 函数通过传递类型,长度和容量来创建切片。容量是可选参数, 默认值为切片长度。make 函数创建一个数组,并返回引用该数组的切片。
i := make([]int, 5, 5)
4)其他
切片可以通过len()方法获取长度,可以通过cap()方法获取容量。
函数append()用于往切片中追加新元素,可以向切片里面追加一个或者多个元素,也可以追加一个切片。
函数copy()会复制切片元素,将源切片中的元素复制到目标切片中,返回复制的元素的个数。