循环结构控制包函数的使用
Posted 星际迷航‖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了循环结构控制包函数的使用相关的知识,希望对你有一定的参考价值。
前言
这里总结的Golang 笔记只适合有点编程基础的人看,比如Java
循环
循环是一段在程序中只出现一次,但可能会连续运行多次的代码。 循环中的代码会运行特定的次数,或者是运行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都运行一次。
for
for循环是一个循环控制结构,可以执行指定次数的循环。
for init; condition; post
for condition
for
for使用
for i := 0; i < 10; i++
for j := 0; j < 10; j++
fmt.Println(i)
while实现
Golang中是没有while的,但是可以通过for去实现while这个功能。
var j = 0
for j < 10
fmt.Printf("%d ", j)
j++
do…while实现
GoLang中也没有do…while的,也是可以通过for去实现do…while 这个功能。
var k = 0
for
fmt.Printf("%d ", k)
if k >= 10
break
k++
break
这里的意思是for可以一直循环的执行,如果k>= 10的时候它会跳出这个循环,否则的话可以一直执行。
var k = 0
for
fmt.Printf("%d ", k)
if k >= 10
break
k++
label使用
golang中可以和label一起使用,更加容易进行流程控制。注意:这里不建议使用,因为很容易造成流程控制混乱
label1:
for i := 0; i < 10; i++
for j := 0; j < 10; j++
fmt.Println(i)
if j == 2
break label1
从如下的结果可以看出j==2的时候直接跳出双层的for循环了。如果单纯的使用break只能跳出内层的for循环,第二次还是进入内层for循环。
continue
continue是可以进行流程控制,意为跳过本次执行,不影响下次循环执行,也不跳出循环。
for i:=0; i<10; i++
if i == 2
continue
fmt.Println("i:", i)
从如上结果看出,仅跳过本次执行(i == 2)
goto介绍
- go语言的goto可以无条件地转移到程序中指定的行。
- goto语句通常与条件语句配合使用,可以用来实现条件的转移,跳出循环体等功能。
- goto一般不建议使用,以免造成程序流程的混乱,使维护程序的难度变大。
package main
import "fmt"
func main()
fmt.Println("1")
goto label1
fmt.Println("2")
fmt.Println("3")
fmt.Println("4")
fmt.Println("5")
label1:
fmt.Println("6")
fmt.Println("7")
包使用
-
在引用别的包的函数时候需要注意的是,函数名必须是大写,大写是公有的可以被其他包引用,小写是私有不能被其他包使用。
-
包名与文件夹不一一对应,但是尽量保证二者是一一对应的,一般都是小写的。
-
在同一个包下,不能有相同的函数名(也不能有相同的全局变量名)。
-
如果你要编译成一个可执行文件,就需要将包名声明为main。
-
基本数据类型和数组都是值传递的,进行值拷贝,在函数内修改不会影响原来的值。
这个是包结构如何使用其他go文件中的变量
main.go
package main
import (
"fmt"
"../utils" // 当前目录
)
func main()
fmt.Println(utils.Age)
utils.go
package utils
var(
Age = 10
)
函数
介绍
函数声明包含一个函数名,参数列表, 返回值列表和函数体。如果函数没有返回值,则返回列表可以省略。函数从第一条语句开始执行,直到执行return语句或者执行函数的最后一条语句。在go中函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了,通过该变量可以对函数进行调用。使用函数可以减少代码的冗余,更加容易维护。
函数的结构
func 函数名(形参列表) (返回值列表)
代码块
return 返回值列表
参数
函数定义时指出,函数定义时有参数,该变量可称为函数的形参。形参就像定义在函数体内的局部变量。但当调用函数,传递过来的变量就是函数的实参,函数可以通过两种方式来传递参数:
- 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
func swap(num1 int, num2 int)
tmp := num1
num1 = num2
num2 = tmp
- 引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。(这里其实也可以理解是值传递,根本不是引用传递,知识拷贝了一份这个地址 然后使用*ptr 去修改这个值)。
func swap(num1 *int, num2 *int)
tmp := *num1
*num1 = *num2
*num2 = tmp
多个参数如何传递
func myfunc(args ...int) //0个或多个参数
func add(a int, args…int) int //1个或多个参数
func add(a int, b int, args…int) int //2个或多个参数
注意:其中args是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数.
返回值
"_"标识符,用来忽略函数的某个返回值,Go 的返回值可以被命名,并且就像在函数体开头声明的变量那样使用。返回值的名称应当具有一定的意义,可以作为文档使用。没有参数的 return 语句返回各个返回变量的当前值,相当于java之中void返回,可以去操作一些全局变量,或者引用类型。直接返回语句仅应当用在像下面这样的短函数中。在长的函数中它们会影响代码的可读性。
func cal(num1 int, num2 int) (int, int)
add := num1 + num2
sub := num1 - num2
return add, sub
命名返回参数可看做与形参类似的局部变量,最后由 return 隐式返回
func add(x, y int) (z int)
z = x + y
return
如上代码示例1返回值有两个的时候,当不想使用哪个值的时候可以使用’_'占位符赋值,这里需要注意的是必须保证顺序。
函数类型
在golang之中其实可以理解函数也是一种数据类型,可以给函数传递函数进行使用,也可以去声明函数等操作。
package main
import "fmt"
type myfunc func(int, int) int // 使用函数别名的功能
func main()
var num1 = 10
var num2 = 20
// 向cal传递add函数
result := cal(add, num1, num2)
fmt.Println(result)
// 进行相加的操作
func add(num1 int, num2 int) int
return num2 + num1
// 向函数中传递一个函数
func cal(function func(int, int) int, num1 int, num2 int) int
return function(num1, num2)
// 使用函数别名
func calus(function myfunc, num1 int, num2 int) int
return function(num1, num2)
// 预先将两个返回值已经定义好,接受返回值的时候还是要按顺序接收
func cals(num1 int, num2 int) (sum int, sub int)
sum = num1 + num2
sub = num2 - num1
return // 返回值这里也不需要明确的指定返回什么
匿名函数
匿名函数由一个不带函数名的函数声明和函数体组成。匿名函数的优越性在于可以直接使用函数内的变量,不必声明。
func main()
getAdd := func(a, b int) int
return a + b
fmt.Println(getAdd(1,2))
闭包
闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。个人理解:在函数1内部的一个函数2引用了他外部变量(函数1中)构成闭包。
// 函数返回的类型 func(int) int
func AddUpper() func(int) int
var n = 10
return func(i int) int
n = n + i
return n
func main()
// 这里相当于f是一个func(int) int的函数类型
f := AddUpper() // 这里的f可以理解java语言中对象,每个对象中n对外是私有的所以f1 中的n 和 f2中的n没有任何关系。
fmt.Println(f(1)) // 11
fmt.Println(f(2)) // 13
通过如上的代码和输出结果可以看出:f可以理解java语言中对象,f对应的函数之中n永远是哪一个所以结果11、13。但是如果f1:= AddUpper()、f2:= AddUpper() 这种情况下是可以进行两个n是不相干的。
defer介绍
1. 关键字 defer 用于注册延迟调用。
2. 这些调用直到 return 前才被执。一般情况是作为释放资源使用(关闭文件、数据库连接、网络连接等)。
3. 多个defer语句从上到下一次放入栈中,执行的时候出栈。
4. defer语句中的变量,在defer声明时就决定了。
func main()
test(10, 20)
func test(num1 int, num2 int) int
defer fmt.Println("num1:", num1)// 如果下面进行赋值等变更的操作,这里值的结果不受任何影响
defer fmt.Println("num2:", num2)
sum := num1+num2
num1++
num2++
fmt.Println("sum:", sum)
return sum
// 输出的结果: sum: 30 num2: 20 num1: 10
从如上的输出结果之中可以看出,上面的介绍,从上到下入栈,输出出栈。
常见函数
字符串函数
常见的字符串处理函数一般都在 “strconv”,"strings"这两个包之中。
import (
"fmt"
"strconv"
"strings"
)
func main()
var str = "hello world"
// 字符串的长度
fmt.Println(len(str))
// 遍历字符串
num := []rune(str)
for i:=0; i<len(num); i++
fmt.Printf("%c", num[i])
fmt.Println()
fmt.Printf("%T\\n", num)
// 字符串转化为整数
val, err := strconv.Atoi("123")
if err!=nil
fmt.Println("转换异常")
else
fmt.Println("转换成功的值为:", val)
fmt.Printf("%T\\n", val)
// 整数转换为字符串
strs := strconv.Itoa(123)
fmt.Println(strs)
fmt.Printf("%T\\n", strs)
// 字符串转化为 []byte
var bytes = []byte("hello")
fmt.Printf("%v\\n", bytes)
// byte转换为字符串
str1 := string([]byte97, 98, 99)
fmt.Println(str1)
// 获取一个数的二进制
var i = 10
j := strconv.FormatInt(int64(i), 2)
fmt.Println(j)
// 判断一个字符串中是否包含另外一个字符串
var str2 = "hello world"
var str3 = "world"
flag := strings.Contains(str2, str3)
fmt.Println(flag)
// 判断字符串中包含几个char
nums:=strings.Count("chinese", "e")
fmt.Println("包含e的个数:", nums)
//不区分大小写去比较
flags := strings.EqualFold("abc", "ABC")
fmt.Println(flags)
// 返回子串第一次出现的字符串中的位置,找不到返回-1
indexs := strings.Index("abcdadsadas", "ad")
fmt.Println(indexs)
// 返回子串出现在字符串最后的位置
lastIndex:=strings.LastIndex("addadadadada", "da")
fmt.Println("最后出现的位置:", lastIndex)
// 将子串替换成另外的子串最后一个参数是n个old替换为new
var str4 = "hello go go"
str4 = strings.Replace(str4, "go", "go语言", 1)
fmt.Println(str4)
// 将字符串拆分为字符数组
arr := strings.Split("hello,world,go,语言", ",")
for i:=0; i<len(arr); i++
fmt.Println(arr[i])
fmt.Println(len(arr))
// 字符串进行大小写转换
var str5 = "sdaAdasfFC"
str6 := strings.ToUpper(str5)
str7 := strings.ToLower(str5)
fmt.Println("转换为大写:", str6, "转换为小写:", str7)
// 去掉字符串左右两边的空格
str8 := strings.TrimSpace(" sdd dssds d ")
fmt.Println(str8)
// 去掉字符串左右两边指定的字符串 Trimleft TrimRight 去掉左边、右边指定的字符串
str9 := strings.Trim("hell!", "!")
fmt.Println(str9)
// 判断字符串是以什么开头、结尾
flag2 := strings.HasPrefix("hello", "h")
flag3 := strings.HasSuffix("hello", "o")
fmt.Println(flag2, flag3)
时间函数
package main
import (
"fmt"
"time"
)
func main()
// 获取当前时间
now := time.Now()
fmt.Printf("当前时间为: %v\\nnow的类型为: %T\\n", now, now)
// 获取年
year := now.Year()
fmt.Println(year)
// 这一年过去多少天
yearDay := now.YearDay()
fmt.Println(yearDay)
// 获取月
month := now.Month()
fmt.Println(month)
// 获取日
day := now.Day()
fmt.Println(day)
// 获取年月日 2021 November 27
date, m, d := now.Date()
fmt.Println(date,m,d)
// 获取时
hour := now.Hour()
fmt.Println(hour)
// 获取分
minute := now.Minute()
fmt.Println(minute)
// 获取秒
second := now.Second()
fmt.Println(second)
// 格式化输出,这里打印出你当前的时间
fmt.Printf(now.Format("2006/01/02 15:04:05"))
init函数
每个源文件中都可以有一个init函数,init函数在main函数之前被调用。被go的运行框架优先于main调用。init函数一般的作用是被用来初始化等操作。
package main
import "fmt"
var test int = test1()
func test1() int
fmt.Println("test")
return 90
func main()
fmt.Println("main")
func init()
fmt.Println("init")
//执行的结果: test init main
注意:如果导入包的话,那么优先进行加载包中变量,然后init方法其次是main中变量然后init的方法,剩下的常规执行顺序。
包变量-----包init----main变量----main中init----main方法代码块
如果文章内容有错误,还请大佬们指导,防止误人子弟。继续冲冲冲!
以上是关于循环结构控制包函数的使用的主要内容,如果未能解决你的问题,请参考以下文章