前
学习笔记,部分图和表格内容都是copy from 《the way to go 》
正
Map
声明.初始化.make
var map1 map[keytype] valuetype
var map1 map[string] int
var map1 = make(map[keytype]valuetype)
key可以是任何可以用 == 或者!= 操作符比较的类型,这里类似java.如果想要使用结构体作为key,需要提供key()和hash()方法
不要使用new 来构造map
存在和删除
因为直接使用map索引不存在的key,可以得到值类型的默认值,所以无法直接判断key-value是否存在.
使用 v , isPresent = map1[key1]
isPresent会返回一个bool值,
删除直接使用delete(map1,key1)
for-range
for key , value := range map1{}
for _, value := range map1{}
只获得valuefor key := range map1{}
只获得key
map类型的切片
例子:
func main() {
// Version A:
items := make([]map[int]int, 5)
for i:= range items {
items[i] = make(map[int]int, 1)
items[i][1] = 2
}
fmt.Printf("Version A: Value of items: %v\n", items)
// Version B: NOT GOOD!
items2 := make([]map[int]int, 5)
for _, item := range items2 {
item = make(map[int]int, 1) // item is only a copy of the slice element.
item[1] = 2 // This 'item' will be lost on the next iteration.
}
fmt.Printf("Version B: Value of items: %v\n", items2)
}
map排序
将key拷贝到一个切片,然后对切片排序,再打印
Package
标准库–copy
archive/tar
和/zip-compress
:压缩(解压缩)文件功能。fmt
-io
-bufio
-path/filepath
-flag
:fmt
: 提供了格式化输入输出功能。io
: 提供了基本输入输出功能,大多数是围绕系统功能的封装。bufio
: 缓冲输入输出功能的封装。path/filepath
: 用来操作在当前系统中的目标文件名路径。flag
: 对命令行参数的操作。
strings
-strconv
-unicode
-regexp
-bytes
:strings
: 提供对字符串的操作。strconv
: 提供将字符串转换为基础类型的功能。unicode
: 为 unicode 型的字符串提供特殊的功能。regexp
: 正则表达式功能。bytes
: 提供对字符型分片的操作。index/suffixarray
: 子字符串快速查询。
math
-math/cmath
-math/big
-math/rand
-sort
:math
: 基本的数学函数。math/cmath
: 对复数的操作。math/rand
: 伪随机数生成。sort
: 为数组排序和自定义集合。math/big
: 大数的实现和计算。
container
-/list-ring-heap
: 实现对集合的操作。list
: 双链表。ring
: 环形链表。
下面代码演示了如何遍历一个链表(当 l 是*List
):for e := l.Front(); e != nil; e = e.Next() { //do something with e.Value }
time
-log
:time
: 日期和时间的基本操作。log
: 记录程序运行时产生的日志,我们将在后面的章节使用它。
encoding/json
-encoding/xml
-text/template
:encoding/json
: 读取并解码和写入并编码 JSON 数据。encoding/xml
:简单的 XML1.0 解析器,有关 JSON 和 XML 的实例请查阅第 12.9/10 章节。text/template
:生成像 HTML 一样的数据与文本混合的数据驱动模板(参见第 15.7 节)。
net
-net/http
-html
:(参见第 15 章)net
: 网络数据的基本操作。http
: 提供了一个可扩展的 HTTP 服务器和基础客户端,解析 HTTP 请求和回复。html
: HTML5 解析器。
runtime
: Go 程序运行时的交互操作,例如垃圾回收和协程创建。reflect
: 实现通过程序运行时反射,让程序操作任意类型的变量。exp
包中有许多将被编译为新包的实验性的包。它们将成为独立的包在下次稳定版本发布的时候。如果前一个版本已经存在了,它们将被作为过时的包被回收。然而 Go1.0 发布的时候并不包含过时或者实验性的包。
正则
一个例子来学吧,说得多记不住
package main
import (
"fmt"
"regexp"
"strconv"
)
func main() {
//目标字符串
searchIn := "John: 2578.34 William: 4567.23 Steve: 5632.18"
pat := "[0-9]+.[0-9]+" //正则
f := func(s string) string{
v, _ := strconv.ParseFloat(s, 32)
return strconv.FormatFloat(v * 2, 'f', 2, 32)
}
if ok, _ := regexp.Match(pat, []byte(searchIn)); ok {
fmt.Println("Match Found!")
}
re, _ := regexp.Compile(pat)
//将匹配到的部分替换为"##.#"
str := re.ReplaceAllString(searchIn, "##.#")
fmt.Println(str)
//参数为函数时
str2 := re.ReplaceAllStringFunc(searchIn, f)
fmt.Println(str2)
}
锁和sync包
表面上暂时当做java中的synchronized关键字来看
互斥锁 : sync.Mutex.Lock()
, sync.Mutex.Unlock()
读写锁 : sync.RWMutex.RLock()
读锁 , sync.RWMutex.Lock()
写锁
精密计算 big包
一个例子 :
// big.go
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
// Here are some calculations with bigInts:
im := big.NewInt(math.MaxInt64)
in := im
io := big.NewInt(1956)
ip := big.NewInt(1)
ip.Mul(im, in).Add(ip, im).Div(ip, io)
fmt.Printf("Big Int: %v\n", ip)
// Here are some calculations with bigInts:
rm := big.NewRat(math.MaxInt64, 1956)
rn := big.NewRat(-1956, math.MaxInt64)
ro := big.NewRat(19, 56)
rp := big.NewRat(1111, 2222)
rq := big.NewRat(1, 1)
rq.Mul(rm, rn).Add(rq, ro).Mul(rq, rp)
fmt.Printf("Big Rat: %v\n", rq)
}
/* Output:
Big Int: 43492122561469640008497075573153004
Big Rat: -37/112
*/
自定义包和可见性
导入包 :import "包的路径或者URL地址"
例如 : import "github.com/org1/pack1"
, import "./pack1/pack1"
当时用 .
作为包的别名时,你可以不通过包名来使用其中的项目
使用go install
安装外部包
结构体和方法
结构体定义
一般方式 :
type identifier struct {
field1 type1
field2 type2
...
}
使用 t := T(v1,v2...)
创建结构体类型变量
使用new 来给一个结构体分配内存,返回的是已分配内存的指针 : var t *T = new(T)
此时 .
被称为选择器,无论是结构体类型还是结构体指针,都可以使用
使用工厂方法创建结构体实例
可以使用go文件对于可见性的规则强制调用方使用工厂方法创建结构体实例
结构体不能使用make, map不能使用new
带标签的结构体
结构体中的字段除了名字和类型外,还有一个可选的标签,但是不可以在一般的编程中使用,只能用反射获得
匿名字段
结构体内可以有没有名字的字段,但是必须有类型,如果是类型是结构体,是组合的意味
方法
Go中的方法并不是属于类的,当然Go就没有类,但是go的方法有一个接受者的东西,这个东西客户以是任何类型,除了指针类型.
一般的定义方式 : func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }
recv 就像是java中的this或python中的self,所以方法不用写在结构体内部,只需要的recv处标识这个函数的接受者是谁就行了.