目录
range
使用range在结合for循环语句的时候能得到索引和值
package main // 固定
import "fmt"
func main() { // 大括号的位置是固定的
a := []int {1, 2, 3, 4}
for index,value := range a{
fmt.Println(index, value)
}
// 或者可以省略某一个参数
for index,_:=range a{
fmt.Println(index)
}
// range还可以用在map上
dict:=map[string]string{"name":"zeng", "age":"21"}
for k, v := range dict{
fmt.Println(k, v)
}
// 也能用来枚举unicode字符串
name:="zeng"
for i,v := range name{
fmt.Println(i, v) // i是索引,v是字符(unicode)本身
}
}
map
map就是键值对,字典的意思,在go中使用字典知识把dict变成了map
package main // 固定
import "fmt"
func main() { // 大括号的位置是固定的
// var map_variable map[key_data_type]value_data_type,前面是键的类型,后面是值的类型
dict:=map[string]string {"name":"zeng", "age":"21"}
fmt.Println(dict)
dict2:=map[int]string {1:"zeng", 2:"zeng2"}
fmt.Println(dict2)
// 可以使用make函数来生成map
dict3:=make(map[string]string)
dict3["1"]="zeng1"
dict3["2"]="zeng2"
fmt.Println(dict3)
for i := range dict3{
fmt.Println(i) // 输出key
}
// delete函数的使用
delete(dict3, "1")
for i := range dict3{
fmt.Println(i) // 输出key
}
}
函数高级用法
package main // 固定
import (
"strings"
"fmt"
)
// 字符串数组中有一个元素让f返回了true,那么整个函数返回true
func Any(vs []string, f func(string) bool) bool {
for _, v := range vs {
if f(v) {
return true
}
}
return false
}
// 只有ss全部元素让f都返回了true,那么整个函数才返回true
func All(vs []string, f func(string) bool) bool {
for _, v := range vs {
if !f(v) {
return false
}
}
return true
}
// 如果ss包含了"zeng"则返回true
func MyFunc(ss string) bool {
res := strings.Index(ss, "zeng")
//fmt.Println(res)
if res != -1 {
return true
} else {
return false
}
}
func main() { // 大括号的位置是固定的
// 如果t串出现在切片中,返回index
ss := "111zengraoli"
fmt.Printf("子串出现的位置是%d\r\n", strings.Index(ss, "z1eng"))
fmt.Printf("子串出现的位置是%d\r\n", strings.Index(ss, "zeng"))
// for循环读取字符串所有的切片
//for _, v := range ss {
// fmt.Println(v)
//}
arrSS1 := []string{"zeng1", "zeng2"}
fmt.Println(Any(arrSS1, MyFunc))
arrSS2 := []string{"z1eng1", "zeng2"}
fmt.Println(Any(arrSS2, MyFunc))
arrSS3 := []string{"zeng1", "zeng2"}
fmt.Println(All(arrSS3, MyFunc))
arrSS4 := []string{"z1eng1", "zeng2"}
fmt.Println(All(arrSS4, MyFunc))
}
字符串函数
package main // 固定
import (
"fmt"
"strings"
)
func main() { // 大括号的位置是固定的
var p = fmt.Println
p("Contains: ", strings.Contains("test", "st")) // 字符串包含
p("Count: ", strings.Count("test", "t")) // 包含字符串的数量
p("HasPrefix: ", strings.HasPrefix("test", "te")) // 是否在前面
p("HasSuffix: ", strings.HasSuffix("test", "st")) // 是否在后面
p("Index: ", strings.Index("test", "e")) // 查找字符串的索引
p("Join: ", strings.Join([]string{"a", "b", "c"}, "++")) // 链接字符串
p("Repeat: ", strings.Repeat("a", 5)) // 重复
p("Replace: ", strings.Replace("foo", "o","l",2)) // 替换
p("Replace: ", strings.Replace("foo", "o","l",-1)) // 替换-1为不限制替换的个数
p("Replace: ", strings.Replace("foo", "o","l",1)) // 替换
p("Split: ", strings.Split("a-b-c-d", "-")) // 分割
p("ToUpper: ", strings.ToUpper("a-b-c-d")) // 转成大写
p("ToLower: ", strings.ToLower("A-B-c-d")) // 转成小写
p("Len: ", len("A-B-c-d")) // 得到字符串的长度
p("Char: ", "hello world"[1]) // 打印第一个字符
}
内置排序函数
package main // 固定
import (
"sort"
"fmt"
)
func main() { // 大括号的位置是固定的
// 排序字符的例子
ss := []string{"c", "a", "b"}
sort.Strings(ss)
fmt.Println("Strings:", ss)
// 排序int数值的例子
ints := []int{7, 2, 4}
sort.Ints(ints)
fmt.Println("Ints: ", ints)
// 用sort来检测切片是否已经按照排序顺序
s := sort.IntsAreSorted(ints)
fmt.Println("Sorted: ", s)
ints2 := []int{7, 2, 4}
s2 := sort.IntsAreSorted(ints2)
fmt.Println("Sorted: ", s2)
}
自定义排序
如果需要使用自定义的Sort函数,则需要重写三个函数,分别是Len、Swap、Less
package main // 固定
import (
"sort"
"fmt"
)
type ByLength []string
func (s ByLength) Len() int {
return len(s)
}
func (s ByLength) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s ByLength) Less(i, j int) bool {
return len(s[i]) < len(s[j])
}
func main() { // 大括号的位置是固定的
// 自定义排序的例子
fruits := []string{"zeng", "rao", "li"}
sort.Sort(ByLength(fruits))
fmt.Println(fruits)
}
接口1
接口比较常用到,需要先定义一个接口名,名字需要和外部提供的接口实现中的参数一致
因为需要在实现中分别去调用具体的实现,所以每一个结构体中的方法需要实现同一个方法
在外部调用接口实现时候,只需要传入不同的struct即可
package main // 固定
import "fmt"
// 定义一个接口
type Mystruct interface {
GetAge() int
}
// 定义一个结构体1
type Mystruct1 struct {
name string
age int
}
// 定义一个结构体2
type Mystruct2 struct {
name string
age int
}
// Mystruct1中所实现的结构的方法
func(mystruct1 Mystruct1) GetAge() int {
return mystruct1.age
}
// Mystruct2中所实现的结构的方法
func(mystruct2 Mystruct2) GetAge() int {
return mystruct2.age
}
// 外部调用方法的实现
func getAge(mystruct Mystruct) int {
return mystruct.GetAge() // 返回结构体面的age方法
}
func main() { // 大括号的位置是固定的
mystruct1 := Mystruct1{"zeng", 21}
mystruct2 := Mystruct2{"zeng", 99}
fmt.Println(getAge(mystruct1))
fmt.Println(getAge(mystruct2))
}
接口2
在某些动态语言里,接口(interface)也被称作协议(protocol),在准备做交互的双方中约定一些规则,在相互不知道对方存在的情况下进行协作
接口最常见的的使用场景,是对包外提供访问,或预留扩展空间
接口通常以er作为名称后缀,方法名是声明组成部分
package main
import "fmt"
type tester interface {
test()
string() string
}
type data struct {}
func (*data) test() {}
func (data) string() string { return "" }
func main() {
var d data // 结构体有test和string的方法
var t tester = &d // 才能让接口进行赋值
t.test()
fmt.Println(t.string())
}