Go Go Go (三)


学习笔记,部分图和表格内容都是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{} 只获得value
for 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处标识这个函数的接受者是谁就行了.

关于方法和类型还有比较麻烦的一些东西


  目录