函数的高级应用
闭包函数:定义在函数内部,对外部作用有引用;
内层函数:定义在函数内部的函数。
简单的举例子:
//函数高级
package main
import "fmt"
//闭包函数:定义在函数内部,对外部作用有引用
//内层函数:定义在函数内部的函数
//go中函数内部定义的函数是不能有名的,需要定义匿名函数:没有名字
func test(a int) {
func() {
fmt.Println("我是内层函数")
}()
}
//闭包函数
func test(a int) (func()) {
//var c int =100
b:=func() {
fmt.Println(a)
fmt.Println("我是闭包函数")
}
return b
}
// 定义一个函数,传入函数,返回函数
func test(a func()) func() {
b:= func() {
fmt.Println("我先执行")
a()
fmt.Println("函数执行完了")
}
return b
}
func test2() {
fmt.Println("xxxx")
}
给类型命别名
格式:type 函数名 类型
//给类型命别名
type MyFunc func(a int,b int) func()
type MyInt int
func test() (MyFunc) {
c:= func(a int,b int) func(){
return func() {
}
}
return c
}
func main() {
//a:=test(3)
//a()
//a:=test2
//a=test(a)
//a()
var a MyInt=10
var b int =90
a=MyInt(b)
fmt.Println(a)
}
类型转换:取别名的的int要对应Myint
var a MyInt=10
var b int =90
a=MyInt(b)
fmt.Println(a)
if-else语句
格式有点类似javascrapy的格式,注意的小点是if后面的{}不能换行,应为没有结束符";"分号。
在 Go 语言规则中,它指定在 } 之后插入一个分号,如果这是该行的最终标记。因此,在if语句后面的 } 会自动插入一个分号。
package main
import (
"fmt"
)
func main() {
num := 10
if num % 2 == 0 { //checks if number is even
fmt.Println("the number is even")
} else {
fmt.Println("the number is odd")
}
}
完整的if-else语句,else必须紧跟在if后面的{}后面,不能空格,不然编译器报错。
package main
import (
"fmt"
)
func main() {
num := 99
if num <= 50 {
fmt.Println("number is less than or equal to 50")
} else if num >= 51 && num <= 100 {
fmt.Println("number is between 51 and 100")
} else {
fmt.Println("number is greater than 100")
}
}
if-else语句特殊的点:在条件中可以定义变量。
//if -else
package main
import "fmt"
func main() {
//a := 90
//if 条件{} 大括号和条件之间不能换行
//if a == 90{
// fmt.Println("a 是90");
//}
//if a >90{
// fmt.Println("a 大于90")
//}else if a<90{
// fmt.Println("a 小于90")
//}else {
// fmt.Println("a 等于90")
//}
//在条件中可以定义变量,但是它的作用于范围只在if判断内部使用
if a :=90;a>90{
fmt.Println("大于")
}else if a==90{
fmt.Println(a)
}
//fmt.Println(a)
}
包的使用
什么是包,为什么要使用包?
到目前为止,我们看到的 Go 程序都只有一个文件,文件里包含一个 main 函数和几个其他的函数。在实际中,这种把所有源代码编写在一个文件的方法并不好用。以这种方式编写,代码的重用和维护都会很困难。而包(Package)解决了这样的问题。
包用于组织 Go 源代码,提供了更好的可重用性与可读性。由于包提供了代码的封装,因此使得 Go 应用程序易于维护。
例如,假如我们正在开发一个 Go 图像处理程序,它提供了图像的裁剪、锐化、模糊和彩色增强等功能。一种组织程序的方式就是根据不同的特性,把代码放到不同的包中。比如裁剪可以是一个单独的包,而锐化是另一个包。这种方式的优点是,由于彩色增强可能需要一些锐化的功能,因此彩色增强的代码只需要简单地导入(我们会在随后讨论)锐化功能的包,就可以使用锐化的功能了。这样的方式使得代码易于重用。
我们会逐步构建一个计算矩形的面积和对角线的应用程序。
通过这个程序,我们会更好地理解包。
注意事项:
goland导包查找规则:默认在GOPATH路径下和GOROOT下查找加载。

一般流程:
-包
-新建一个文件夹,内部写很多go文件,但是包名必须一致
-如果想在外部包使用,首字母必须大写
-在其他包中使用
-import "mypackage"
-mypackage.Test1()
-下载第三方包
go get github.com/astaxie/beego
beego、gin 框架
例子:自定义包的导入使用
先自定义一个包下面有两个函数:

mypackage包下的package1,如果想要让外部导入使用,函数名必须首字母大写。
package mypackage
// 通常情况下,包名就是文件夹名,在同一个文件夹下,包名必须一致。
func Test(a,b int) int {
return a+b
}
mypackage包下的package2
package mypackage
import "fmt"
//在同一个包下,变量,函数,都不能重复定义
func Test1() {
fmt.Println("包的使用")
}
导入使用:
//包的使用
package main
import (
"fmt"
"mypackage"
)
func main() {
//想使用mypackage包下的test函数和test1函数
mypackage.Test1()
mypackage.Test(1,2)
fmt.Println("xxx")
}

for 循环
循环语句是用来重复执行某一段代码。
for 是 Go 语言唯一的循环语句。Go 语言中并没有其他语言比如 C 语言中的 while 和 do while 循环。
基本语法结构:

简单完整的for语法结构
//for 循环
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
fmt.Printf(" %d",i)
}
}
for语法的其他写法,三部分可以省略
//for循环
package main
import "fmt"
func main(){
//三部分,都可以省略
//先省略第一部分
//i :=0
//for ;i<10;i++{
// fmt.Println(i)
//}
//省略第三部分
//i :=0
//for ;i<10;{
// i++
// fmt.Println(i)
//}
//省略第二部分
//for ;;{
// fmt.Println("xxxx")
//}
//死循环
//for {
// fmt.Println("xxxx")
//}
//只写条件 for 条件{} 等同于while循环
for {
fmt.Println("just do it")
}
}
结合break和countnue的使用和其他语言的语法结构一致的;
break 语句用于在完成正常执行之前突然终止 for 循环,之后程序将会在 for 循环下一行代码开始执行。
continue 语句用来跳出 for 循环中当前循环。在 continue 语句后的所有的 for 循环语句都不会在本次循环中执行。循环体会在一下次循环中继续执行。
//for 循环
package main
import "fmt"
func main(){
//break和continue跟其他任何语言都一样
for i:=0;i<10;i++{
if i==5{
break
}
fmt.Println(i)
}
for i:=0;i<10;i++{
if i==5{
continue
}
fmt.Println(i)
}
switch 语句
switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。
它可以被认为是替代多个 if else 子句的常用方式。
简单的理解,即使用switch替代if else条件语句
基本用法:
package main
import (
"fmt"
)
func main() {
finger := 4
switch finger {
case 1:
fmt.Println("a")
case 2:
fmt.Println("b")
case 3:
fmt.Println("c")
case 4:
fmt.Println("d")
case 5:
fmt.Println("e")
}
}
默认情况(Default Case)
当其他情况都不匹配时,将运行默认情况,类似if-else if -else
package main
import (
"fmt"
)
func main() {
switch finger := 8; finger {
case 1:
fmt.Println("Thumb")
case 2:
fmt.Println("Index")
case 3:
fmt.Println("Middle")
case 4:
fmt.Println("Ring")
case 5:
fmt.Println("Pinky")
default: // 默认情况
fmt.Println("incorrect finger number")
}
}
多表达式判断
通过用逗号分隔,可以在一个 case 中包含多个表达式。
package main
import (
"fmt"
)
func main() {
letter := "i"
switch letter {
case "a", "e", "i", "o", "u": // 一个选项多个表达式
fmt.Println("vowel")
default:
fmt.Println("not a vowel")
}
}
在 case "a","e","i","o","u": 这一行中,列举了所有的元音。只要匹配该项,则将输出 vowel。
无表达式的 switch
在 switch 语句中,表达式是可选的,可以被省略。如果省略表达式,则表示这个 switch 语句等同于 switch true,并且每个 case 表达式都被认定为有效,相应的代码块也会被执行。
package main
import (
"fmt"
)
func main() {
num := 75
switch { // 表达式被省略了
case num >= 0 && num <= 50:
fmt.Println("num is greater than 0 and less than 50")
case num >= 51 && num <= 100:
fmt.Println("num is greater than 51 and less than 100")
case num >= 101:
fmt.Println("num is greater than 100")
}
}
在上述代码中,switch 中缺少表达式,因此默认它为 true,true 值会和每一个 case 的求值结果进行匹配。case num >= 51 && <= 100: 为 true,所以程序输出 num is greater than 51 and less than 100。这种类型的 switch 语句可以替代多个 if else 子句。
Fallthrough 语句
简单的理解:就是当语句中由Fallthrough 这个关键字,就无条件的执行它后面的语句。
package main
import "fmt"
func main(){
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")
}
}
func test5() {
fmt.Println("xxxxxx")
}
}
fallthrough 语句应该是 case 子句的最后一个语句。如果它出现在了 case 语句的中间,编译器将会报错:fallthrough statement out of place。
数组和切片
数组
数组是同一类型元素的集合。
例如,整数集合 5,8,9,79,76 形成一个数组。Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组。
(译者注:当然,如果是 interface{} 类型数组,可以包含任意类型)
数组的声明
一个数组的表示形式为 [n]T。n 表示数组中元素的数量,T 代表每个元素的类型。元素的数量 n 也是该类型的一部分
简单例子
package main
//数组 在定义阶段,长度和类型就固定了,以后不能更改
import "fmt"
func main() {
var a [3]int
a[1]=20
a[2]=100
fmt.Println(a)
}
结果:

数组的其他情况
//数组 在定义阶段,长度和类型就固定了,以后不能更改
package main
import "fmt"
func main() {
//var a [5]int //定义了一个长度为5的int类型数组
//a[1]=100 //把2个位置放上100
//fmt.Println(a)
//定义并赋初值
//var a [6]int=[6]int{1,2,3,4,5,6}
//var a =[6]int{1,2,3}
//a :=[6]int{1,2,3}
//a[5]=100
//fmt.Println(a)
//第99个位置设为99
//a :=[100]int{1,2,98:99,87:88}
////a[-9]=19 不支持
//fmt.Println(a)
//数组是值类型
//所有的函数传参都是copy传递
//a:=[4]int{1,2,3}
//test6(a)
//fmt.Println(a)
//数组的长度 内置函数len
//a:=[4]int{1,2,3}
//fmt.Println(len(a))
//数组大小是类型一部分
//var a [4]int=[4]int{1,2,}
//var b [5]int=[5]int{4,5,}
//a=b
//fmt.Println(a)
//与或非
//&& || !
//a:=10
//if !(a>9||a<6){
//
//}
//数组迭代
//var a [4]int=[4]int{1,2,}
//for i:=0;i<len(a);i++{
// fmt.Println(a[i])
//}
//通过range迭代
//for i,v:=range a {
////for i:=range a {
// fmt.Println("------",i)
// fmt.Println(v)
//}
}
多维数组
package main
import "fmt"
func main(){
//多维数组
var a [7][2]int // 7组2个元素的元组
a[0][1]=100
fmt.Println(a)
}
func test6(b [4]int) {
b[3]=100
fmt.Println(b)
}
}

切片
切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。
创建一个切片
带有 T 类型元素的切片由 []T 表示
package main
import (
"fmt"
)
func main() {
a := [5]int{76, 77, 78, 79, 80}
var b []int = a[1:4] // creates a slice from a[1] to a[3]
fmt.Println(b)
}值为 [77 78 79]
来源:https://www.cnblogs.com/Gaimo/p/12019251.html