字符串相关操作
strings包:
func Contains(s, substr string) bool
func ContainsAny(s, chars string) bool // 是否包含chars内的任意字符
func ContainsRune(s string, r rune) bool
func Count(s, sep string) int
func EqualFold(s, t string) bool // 字符串是否相等,忽略大小写
func Fields(s string) []string // 字符串按空白分割
func FieldsFunc(s string, f func(rune) bool) []string // 字符串按满足自定义条件的特定字符分割
func HasPrefix(s, prefix string) bool // 前缀
func HasSuffix(s, suffix string) bool // 后缀
func Index(s, sep string) int // 子串位置,不包含返回-1
func IndexAny(s, chars string) int // chars中的字符首次出现位置
func IndexByte(s string, c byte) int
func IndexFunc(s string, f func(rune) bool) int
func IndexRune(s string, r rune) int
func Join(a []string, sep string) string // 使用sep连接字符串
func LastIndex(s, sep string) int
func LastIndexAny(s, chars string) int
func LastIndexFunc(s string, f func(rune) bool) int // 返回最后一个满足f的字符下标,不满足返回-1
func Map(mapping func(rune) rune, s string) string // 按照mapping函数改变字符内容
func Repeat(s string, count int) string // 相当于python中的 "str"*cnt
func Replace(s, old, new string, n int) string // 字符串替换,若n小于0,最大替换
func Split(s, sep string) []string // 若sep为空,按字符分割
func SplitAfter(s, sep string) []string
func SplitAfterN(s, sep string, n int) []string
func SplitN(s, sep string, n int) []string
func Title(s string) string // 单词首字母大写
func ToLower(s string) string
func ToLowerSpecial(_case unicode.SpecialCase, s string) string
func ToTitle(s string) string
func ToTitleSpecial(_case unicode.SpecialCase, s string) string
func ToUpper(s string) string
func ToUpperSpecial(_case unicode.SpecialCase, s string) string
func Trim(s string, cutset string) string // 头尾剪去cutset中的字符
func TrimFunc(s string, f func(rune) bool) string
func TrimLeft(s string, cutset string) string
func TrimLeftFunc(s string, f func(rune) bool) string
func TrimPrefix(s, prefix string) string //去前缀,不同于TrimLeft
func TrimRight(s string, cutset string) string
func TrimRightFunc(s string, f func(rune) bool) string
func TrimSpace(s string) string
func TrimSuffix(s, suffix string) string
strconv包:
func AppendBool(dst []byte, b bool) []byte
func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte
func AppendInt(dst []byte, i int64, base int) []byte
func AppendQuote(dst []byte, s string) []byte
func AppendQuoteRune(dst []byte, r rune) []byte
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte
func AppendQuoteToASCII(dst []byte, s string) []byte
func AppendUint(dst []byte, i uint64, base int) []byte
func Atoi(s string) (i int, err error) // string to int,并返回error
func CanBackquote(s string) bool
func FormatBool(b bool) string // 将布尔类型转成字符串形式
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string // 进制转换
func IsPrint(r rune) bool
func Itoa(i int) string // int转string
func ParseBool(str string) (value bool, err error) // 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False, 其他类型返回错误
func ParseFloat(s string, bitSize int) (f float64, err error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func Quote(s string) string
func QuoteRune(r rune) string
func QuoteRuneToASCII(r rune) string
func QuoteToASCII(s string) string
func Unquote(s string) (t string, err error)
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
Go中的时间和日期类型
获取当前时间, now := time.Now()
time.Now().Day(),time.Now().Minute(),time.Now().Month(),time.Now().Year()
time.Duration用来表示纳秒
格式化:
now := time.Now()
fmt.Println(now.Format("02/1/2006 15:04"))
fmt.Println(now.Format("2006/1/02 15:04"))
fmt.Println(now.Format("2006/1/02"))
流程控制
if/else
注意else花括号不能另起一行
if condition1 {
} else if condition2 {
} else if condition3 {
} else {
}
switch
switch var {
case var1:
case var2:
case var3:
default:
}
switch i := 2;{
case i > 0 && i < 10:
fmt.Println("i > 0 and i < 10")
case i > 10 && i < 20:
fmt.Println("i > 10 and i < 20")
default:
fmt.Println("default")
}
for语句
注意for循环不写圆括号!
for i := 0 ; i < 100; i++ {
fmt.Printf("i=%d\n", i)
}
也可以当while循环来写
for i > -1{
fmt.Println(i)
}
死循环可以这样写
for {
fmt.Println(i)
}
for range语句:
str := "hello world,中国"
for i, v := range str {
fmt.Printf("index[%d] val[%c] len[%d]\n", i, v, len([]byte(string(v))))
}
函数详解
函数声明语法
func 函数名 (参数列表) [(返回值列表)] {}
func add() {
}
func add(a int, b int) {
}
func add(a, b int) (int, int) {
}
golang函数特点
- 不支持重载,一个包不能有两个名字一样的函数
- 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
- 支持匿名函数
- 支持多返回值
- 函数不支持互相比较,只能和nil比较
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
c := add
fmt.Println(c)
sum := c(10, 20)
fmt.Println(sum)
if ( c == add ) { // invalid operation: c == add (func can only be compared to nil)
fmt.Println("c equal add")
}
}
函数也是一种类型,可以作为参数传递
package main
import "fmt"
type add_func func(int, int) int
func add(a, b int) int {
return a + b
}
func operator(op add_func, a int, b int) int {
return op(a, b)
}
func main() {
c := add
fmt.Println(c)
sum := operator(c, 100, 200)
fmt.Println(sum)
}
函数参数传递方式
- 值传递
- 引用传递
无论是值传递,还是引用传递,传递给函数的都是变量的副本;不过,值传递是值的拷贝,引用传递是地址的拷贝;一般来说,地址拷贝更为高效,而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。
map、slice、chan、interface默认以引用的方式传递。
命名返回值的名字
golang函数的返回值可以有名字。
func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a + b)/2
return
}
##### _标识符,用来忽略返回值
func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a +b)/2
return
}
func main() {
sum, _ := calc(100, 200)
}
可变参数
// 0个或多个参数
func add(args...int) int {
}
// 1个或多个参数
func add(a int, args...int) int {
}
// 2个或多个参数
func add(a int, b int, args...int) int {
}
package main
import "fmt"
func add(a int, args...int) int {
sum := a
for _, v := range args{
sum += v
}
return sum
}
func main() {
fmt.Println(add(1, 2, 3, 4, 5))
}
其中args是一个slice,我们可以通过args[index]依次访问所有参数,通过len(args)来判断传递参数的个数。
defer关键字
defer的使用:
- 当函数返回时,执行defer语句,因此,可以用来做资源清理(关闭文件句柄、释放锁、释放数据库连接等)
- 多个defer语句,按先进后出的方式执行
- defer语句中的变量,在defer声明时就决定了
package main
import "fmt"
func aaa() {
i := 100
defer fmt.Println(i)
i++
return
}
func fff() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d", i)
}
}
func main() {
aaa()
fff()
}
// 100
// 43210
注意下面的例子,只有文件打开成功了,才执行关闭的动作,否则会panic!
func read() {
file, err := os.Open("test.txt")
if err != nil{
fmt.Println(err)
return
}
defer file.Close()
//文件操作
}
内置函数
close:主要用来关闭channel
len:用来求长度,比如string、array、slice、map、channel
new:用来分配内存,主要用来分配值类型,比如int、struct,返回的是指针
make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
append:用来追加元素到数组、slice中
panic和recover:用来做错误处理
new和make的区别:
new用于在堆上申请内存,返回指针类型;make也是用于内存分配的,但是和new不同,它只用于chan、map以及切片的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
闭包
闭包就是一个函数和与其相关的引用环境组合而成的实体,即 闭包 = 代码块 + 环境。
package main
import "fmt"
func main() {
var f = Adder()
fmt.Print(f(1)," - ")
fmt.Print(f(20)," - ")
fmt.Print(f(300))
}
func Adder() func(int) int {
var x int
return func(delta int) int {
x += delta
return x
}
}
// 1 - 21 - 321
package main
import (
"fmt"
"strings"
)
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
func main() {
func1 := makeSuffixFunc(".bmp")
func2 := makeSuffixFunc(".jpg")
fmt.Println(func1("test"))
fmt.Println(func2("test"))
}
// test.bmp
// test.jpg