目录
一、概述
1、函数
1.1、函数-递归调用
1.2、init函数
1.3、匿名函数
1.4、闭包
1.5、函数中-defer
1.6、函数参数的传递方式
2、包
3、字符串中常用的函数
基本语法:
func 函数名 (形参列表) (返回值类型列表) {
执行语句...
return 返回值列表
}
1.形参列表,表示函数的输入
2.函数中的语句,表示为了实现某一功能代码块
3.函数可以有返回值,也可以没有
4.Go函数支持返回多个值,这一点是其他编程语言没有的。
5.如果返回多个值,在接收时,希望忽略某个返回值,则使用 _符号表示占位忽略
6.如果返回值只有一个,(返回值类型列表)可以不写()
7.形参列表和返回值类型列表的数据类型可以是值类型和引用类型
8.函数名的命名规范,首字母不能是数字,首字母大写该函数可以被本包和其他包文件使用,类似public,反之小写,类似private。
9.函数中的变量是局部的,函数外不生效
10.基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。
11.如果希望函数内的变量能够修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用。
12.Go函数不支持重载
13.在Go中,函数也是一种数据类型,可以赋值给一个变量,该变量就是一个函数类型的变量,通过该变量可以对函数调用
14.函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用!
15.为了简化数据类型定义,Go支持自定义数据类型
基本语法:
type 自定义数据类型名 数据类型 //理解:相当于一个别名
例:type myInt int //这时myInt等价int来使用
16.支持对函数返回值命名
例:
func getSum(n1 int,n2 int) (sum int) {
sum = n1+n2
return
}
17.使用 _标识符,忽略返回值
18.Go支持可变参数
func sum(args... int) sum int{//支持0-多个参数
}
func sum(n1 int,args... int) sum int{//支持1-多个参数
}
说明:args是slice,通过args[index]可以访问到各个值
如果一个函数的形参列表中有可变参数,则可变参数需要放在形参列表最后。
package main
import (
"fmt"
)
func getSum(n1 int,n2 int) int {
return n1 + n2
}
func getSumByFunc(funcVar func(int,int) int,n1 int,n2 int) int {
return funcVar(n1,n2)
}
func main() {
a :=getSum
fmt.Printf("a的类型%T,getSum的类型%T\n",a,getSum)
res := a(10,20)//等价于getSum(10,20)
fmt.Println("res=",res)
res2 := getSumByFunc(getSum,20,30)
fmt.Println("res2=",res2)
}
package main
import (
"fmt"
)
var age = test()
func test() int{
fmt.Println("test()--age")
return 10
}
func main() {
fmt.Println("main()")
}
func init() {
fmt.Println("init()")
}
//输出结果:
//test()--age
//init()
//main()
面试题:
案例:main.go引入utils.go,都含有变量定义,init函数时执行的流程?
1.utils.go 变量定义
2.utils.go init函数
3.main.go 变量定义
4.main.go init函数
5.main.go main函数
package main
import (
"fmt"
)
var (
//全局匿名函数
fun1 = func (n1 int ,n2 int) int {
return n1 + n2
}
)
func main() {
//方式1:
res := func (n1 int,n2 int) int{
return n1 + n2
}(10,20)
fmt.Println("res=",res)
//方式2:
a := func (n1 int,n2 int) int{
return n1 - n2
}
res1 := a(20,15)
fmt.Println("res1=",res1)
res2 := fun1(20,30)
fmt.Println("res2=",res2)
}
闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)
package main
import (
"fmt"
)
//累加器
func add() func (int)int{
var n int = 10
return func (x int) int{
n = n + x
return n
}
}
func main() {
f := add()
fmt.Println(f(1))//11
fmt.Println(f(2))//13
}
说明: add是一个函数,返回的数据类型是fun (int) int 闭包的说明
var n int = 10
return func (x int) int{
n = n + x
return n
}
//返回的是一个匿名函数,但是这个匿名函数引用到函数外的n,因此这个匿名函数和n就形成一个整体,构成闭包。
//可以理解:闭包是类,函数是操作,n是字段函数和使用的n构成闭包
//当我们反复调用函数f时,因为n是初始化一次,因此每调用一次就进行累计。
//闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。
//闭包可以保留上次引用的某个值,可以反复使用
package main
import (
"fmt"
)
func main() {
sum(10,20)
}
func sum(n1 int ,n2 int) int{
defer fmt.Println("n1=",n1)
defer fmt.Println("n2=",n2)
n1++
n2++
res := n1+n2
fmt.Println("res=",res)
return res
}
包的三大作用
基本语法:
package 包名
引入包基本语法
import "包的路径"
package main
import (
f "fmt"
)
func main() {
f.Println("Hello World!")
}
1、统计字符串的长度,按字节 len(str)
len()内建函数,在godoc文档的builtin下 func len(v Type) int:内建函数len返回 v 的长度,这取决于具体类型
2、字符串遍历,同时处理有中文的问题r := []rune(str)
3、字符串转整数: n,err :=strconv.Atoi("45")
4、整数转字符串: str =strconv.Itoa(12345)
5、字符串转[]byte:var bytes =[]byte["hello go"]
6、[]byte转字符串: str=string([]byte{97,98,99})
7、10进制转2,8,16进制:str=strconv.FormatInt(123,2) //2->8,16
8、查找子串是否在指定的字符串中:strings.Contains("seafood","foo") //true
9、统计一个字符串有几个指定的子串: strings.Count("ceheese","e") //4
10、不区分大小写的字符串比较(==是区分字母大小写的):fmt.Println(strings.EqualFold("abc","Abc")) //true
11、返回子串在字符串第一次出现的index值,如果没有返回-1:strings.Index("NLT_abc","abc") //4
package main
import (
"fmt"
"strconv"
"strings"
)
func main(){
// 1、统计字符串的长度,按字节
str1 := "hello北"
fmt.Println("str1 len=",len(str1))
// 2、字符串遍历,同时处理有中文的问题
str2 := "hello北京"
r := []rune(str2)
for i :=0;i
12、返回子串在字符串最后一次出现的index,如没有返回-1:strings.LastIndex("go golang","go")
13、将指定的子串替换成另外一个子串:strings.Replace("go go hello","go","go语言",n) //n可以指定你希望替换几个,如果n=-1表示全部替换
14、按照指定的某个字符,为分割标识,将一个字符串拆分成字符串数组:strings.Split("hello,world,ok",",")
15、将字符串的字母进行大小写的转换:strings.ToLower("Go") //strings.ToUpper("Go") //GO
16、将字符串左右两边的空格去掉,strings.TrimSpace(" tn a lone go lang ")
17、将字符串左右两边的空格去掉:strings.Trim("! hello! "," !") //将左右两边!和" "去掉
18、将字符串左边指定的字符去掉:strings.TrimLeft("! hello! "," !") //将左边!和" "去掉
19、将字符串右边指定的字符去掉:strings.TrimRight("! hello! "," !") //将右边!和" "去掉
20、判断字符串是否以指定的字符串开头:strings.HasPrefix("ftp://192.168.10.1","ftp") //true
21、判断字符串是否以指定的字符串结束:strings.HasSuffix("ftp://192.168.10.1sss","sbd") //false
package main
import (
"fmt"
"strings"
)
func main(){
// 12、返回子串在字符串最后一次出现的index,如没有返回-1
str12 := strings.LastIndex("go golang","go")
fmt.Printf("str12=%v\n",str12)
// 13、将指定的子串替换成另外一个子串
str13 := strings.Replace("go go hello","go","go语言",-1) //n可以指定你希望替换几个,如果n=-1表示全部替换
fmt.Printf("str132=%v\n",str13)
// 14、按照指定的某个字符,为分割标识,将一个字符串拆分成字符串数组
str14 := strings.Split("hello,world,ok",",")
fmt.Printf("str14=%v\n",str14)
// 15、将字符串的字母进行大小写的转换
str15 := strings.ToLower("Go") //strings.ToUpper("Go") //GO
fmt.Printf("str15=%v\n",str15)
// 16、将字符串左右两边的空格去掉
str16 := strings.TrimSpace(" tn a lone go lang ")
fmt.Printf("str16=%v\n",str16)
// 17、将字符串左右两边的空格去掉
str17 := strings.Trim("! hello! "," !") //将左右两边!和" "去掉
fmt.Printf("str17=%v\n",str17)
// 18、将字符串左边指定的字符去掉
str18 := strings.TrimLeft("! hello! "," !") //将左边!和" "去掉
fmt.Printf("str18=%v\n",str18)
// 19、将字符串右边指定的字符去掉
str19 := strings.TrimRight("! hello! "," !") //将右边!和" "去掉
fmt.Printf("str19=%v\n",str19)
// 20、判断字符串是否以指定的字符串开头
fmt.Println(strings.HasPrefix("ftp://192.168.10.1","ftp"))
// 21、判断字符串是否以指定的字符串结束
fmt.Println(strings.HasSuffix("ftp://192.168.10.1sss","sbd"))
}
干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!