Go 语言学习案例

KeppelTed 发布于1年前

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mhw828/article/details/80703706

GOLang 笔记

2018/1/1 12:12:17

环境搭建

Go软件下载地址

安装

Go 语言学习案例

Go 语言学习案例

Go 语言学习案例

Go 语言学习案例

Go 语言学习案例

Go 语言学习案例

推荐IDE GoLand

安装

IDE 注册服务器

http://btsha.com:41017

IDE 配置

Go 语言学习案例

Go 语言学习案例

API 地址

https://studygolang.com/pkgdoc

环境变量介绍

GOPATH

工程目录

GOROOT

Go软件的安装目录

经典程序 Hello World

// 必须为main
package main

import "fmt"

//程序入口
func main() {
    //打印输出
    fmt.Println("Hello World")
}

25关键字

break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

36 个预定义标识符

append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

变量

package main

import "fmt"

// 变量  字符串
var name = "ms~go"

// 整数
var age = 23

//字符串
var address = "beijing"

// 布尔类型
var sex = true

//常量
const year = 2018

//字符
var c = 'c'




func main() {

    fmt.Println(name)
    fmt.Println(age)
    fmt.Println(sex)
    fmt.Println(year)

    var a = 1.5
    var b = 2.5
    //计算加法
    fmt.Println(a + b)

}
var (
    a int     = 10
    b float64 = 100
)
a, b := 20, 30
_, b := 34, 35

丢弃34

“_” 代表丢弃的意思

数学运算

package main

import "fmt"

func main() {

    var a = 0xff

    var b = 10

    fmt.Println(a + b)
    fmt.Println(a - b)
    fmt.Println(a * b)
    fmt.Println(a / b)
    fmt.Println(a % b)
    fmt.Println(a > b)
    fmt.Println(a < b)
    fmt.Println(a <= b)
    fmt.Println(a >= b)
    fmt.Println(a >> 1)
    fmt.Println(b << 1)
    fmt.Println(b | 1)
    fmt.Println(b & 1)
    fmt.Println(b != 1)

}

随机数

package main

import (
    "fmt"
    "time"
    "math/rand"
)

func main() {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    for i:=0; i<10; i++ {
        fmt.Println(r.Intn(100))
    }
}

数组

package main

import (
    "fmt"
    "time"
    "math/rand"
)

func main() {

    // 常量数组长度
    const N = 10
    //声明数组
    var arr = [N]int{}
    //随机数
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    //循环赋值
    for i := 0; i < len(arr); i++ {
        //赋值
        arr[i] = r.Intn(0xff)
    }
    //打印数组
    fmt.Println(arr)

    /*******************************************

                    冒泡排序

     ********************************************/

    //:=自动匹配变量类型
    num := len(arr)
    //花括号{必须在这一行 if也一样
    for i := 0; i < num; i++ {
        for j := i + 1; j < num; j++ {
            if arr[i] > arr[j] {
                //相比某语言不需要临时交换变量
                arr[i], arr[j] = arr[j], arr[i]
            }
        }
    }
    //输出排序后的数组
    fmt.Println(arr)

}

指针

package main

import "fmt"

func main() {

    // 声明变量
    var a int = 10

    var b int = 10

    //打印地址
    fmt.Println("pointer address : %x", &a)

    fmt.Println("pointer address : %x", &b)

    //判断地址是否相同
    fmt.Println(&a == &b)

    //值赋值
    var c = a
    //值赋值
    var d = b

    //打印值
    fmt.Println(c)
    //打印地址
    fmt.Println("pointer address : %x", &c)
    //打印值
    fmt.Println(d)
    //打印地址
    fmt.Println("pointer address : %x", &d)

    //取地址
    var e = &a
    //取地址
    var f = &a
    //输出地址
    fmt.Println("pointer address : %x", &e)
    //输出地址
    fmt.Println("pointer address : %x", &f)
    //输出值
    fmt.Println(e)
    //输出值
    fmt.Println(f)
    //判断地址是否相同
    fmt.Println(e == f)
    //指针类型
    var ip *int = &a
    //打印指针
    fmt.Println(ip)

    //二级指针
    var jp **int = &ip
    fmt.Println(jp)

    //三级指针
    var kp ***int = &jp;
    fmt.Println(kp)

    arr := []int{10, 100, 200}
    var i int

    for i = 0; i < len(arr); i++ {
        fmt.Printf("a[%d] = %d  |  %x \n", i, arr[i], &arr[i])
    }

}

MD5

package main

import (
    "crypto/md5"
    "fmt"
    "encoding/hex"
)

func main() {
    md5Ctx := md5.New()
    md5Ctx.Write([]byte("ms~go"))
    cipherStr := md5Ctx.Sum(nil)
    fmt.Println(cipherStr)
    fmt.Println(hex.EncodeToString(cipherStr))
}

sha 256

package main

    import (
        "crypto/sha256"
        "fmt"
    )

    func main() {
        h := sha256.New()
        h.Write([]byte("ms~go"))
        fmt.Printf("%x", h.Sum(nil))
    }

iota

package main

import "fmt"

func main() {

    //为 0
    const a = iota
    const (
        //没增加一行+1
        b = iota
        c = iota
        d = iota

        e, f = iota, iota
        // 同一行数值相等
        g, h, i, j, k = iota, iota, iota, iota, iota
    )
    fmt.Printf("a = %d , b = %d , c = %d , d = %d , e = %d , f = %d , g = %d , h = %d , i = %d , j = %d , k = %d ", a, b, c, d, e, f, g, h, i, j, k)
    //每次 const 出现时,都会让 iota 初始化为0.
    const l = iota

    fmt.Println(l)

}
// 自增长类型
const (
    a = iota
    b
    c
    d
)

使用 “_” 可以跳过值

const (
    a = iota
    b
    c
    // 使用 "_" 可以跳过值
    _
    _
    d
)

位掩码表达式

const(
    a=1<<iota
    b
    c
    d
    e
    f
    _
    g
    h
)

fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
fmt.Println(g)
fmt.Println(h)


GOROOT=D:\Go #gosetup
GOPATH=E:\GoProject;D:\Go #gosetup
D:\Go\bin\go.exe build -i -o C:\Users\maohuawei\AppData\Local\Temp\___go_build_main_go.exe E:/GoProject/src/ExampleCode/main/main.go #gosetup
"C:\Program Files\JetBrains\GoLand 2018.1.4\bin\runnerw.exe" C:\Users\maohuawei\AppData\Local\Temp\___go_build_main_go.exe #gosetup
1
2
4
8
16
32
128
256

定义数量级

type ByteSize float64

const (
    _           = iota                   // ignore first value by assigning to blank identifier
    KB ByteSize = 1 << (10 * iota) // 1 << (10*1)
    MB                                   // 1 << (10*2)
    GB                                   // 1 << (10*3)
    TB                                   // 1 << (10*4)
    PB                                   // 1 << (10*5)
    EB                                   // 1 << (10*6)
    ZB                                   // 1 << (10*7)
    YB                                   // 1 << (10*8)
)

文件

package main

import (
    "bufio" //缓存IO
    "fmt"
    "io"
    "io/ioutil" //io 工具包
    "os"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

/**
 * 判断文件是否存在  存在返回 true 不存在返回false
 */
func checkFileIsExist(filename string) bool {
    var exist = true
    if _, err := os.Stat(filename); os.IsNotExist(err) {
        exist = false
    }
    return exist
}

/**
  from: http://www.isharey.com/?p=143
*/

func main() {
    var wireteString = "测试n"
    var filename = "./output1.txt"
    var f *os.File
    var err1 error
    /***************************** 第一种方式: 使用 io.WriteString 写入文件 ***********************************************/
    if checkFileIsExist(filename) { //如果文件存在
        f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
        fmt.Println("文件存在")
    } else {
        f, err1 = os.Create(filename) //创建文件
        fmt.Println("文件不存在")
    }
    check(err1)
    n, err1 := io.WriteString(f, wireteString) //写入文件(字符串)
    check(err1)
    fmt.Printf("写入 %d 个字节n", n)

    /*****************************  第二种方式: 使用 ioutil.WriteFile 写入文件 ***********************************************/
    var d1 = []byte(wireteString)
    err2 := ioutil.WriteFile("./output2.txt", d1, 0666) //写入文件(字节数组)
    check(err2)

    /*****************************  第三种方式:  使用 File(Write,WriteString) 写入文件 ***********************************************/
    f, err3 := os.Create("./output3.txt") //创建文件
    check(err3)
    defer f.Close()
    n2, err3 := f.Write(d1) //写入文件(字节数组)
    check(err3)
    fmt.Printf("写入 %d 个字节n", n2)
    n3, err3 := f.WriteString("writesn") //写入文件(字节数组)
    fmt.Printf("写入 %d 个字节n", n3)
    f.Sync()

    /***************************** 第四种方式:  使用 bufio.NewWriter 写入文件 ***********************************************/
    w := bufio.NewWriter(f) //创建新的 Writer 对象
    n4, err3 := w.WriteString("bufferedn")
    fmt.Printf("写入 %d 个字节n", n4)
    w.Flush()
    f.Close()
}

字典

package main

import "fmt"

func main() {


    m:=make(map[string]string)

    m["a"]="a"
    m["b"]="b"
    m["c"]="c"

    // 打印字典
    fmt.Println(m)
    //字典长度
    fmt.Println(len(m))
    //根据键取值
    fmt.Println(m["c"])
    //删除
    delete(m,"b")

    fmt.Println(m)

}

字符串

package main

import (
    "fmt"
    "strings"
)

func main() {

    var print = fmt.Println
    print(strings.Contains("MS~GO","MS"))
    print(strings.Join([]string{"a", "b", "c"}, "~"))
    print(strings.Count("ms~go go go","go"))
    print(strings.EqualFold("s","s"))
    print(strings.Fields("abc"))
    //比较
    print(strings.Compare("aaa","aaa"))

}

自定义排序

package main
import "sort"
import "fmt"
// 为了能够使用自定义函数来排序,我们需要一个
// 对应的排序类型,比如这里我们为内置的字符串
// 数组定义了一个别名ByLength
type ByLength []string
// 我们实现了sort接口的Len,Less和Swap方法
// 这样我们就可以使用sort包的通用方法Sort
// Len和Swap方法的实现在不同的类型之间大致
// 都是相同的,只有Less方法包含了自定义的排序
// 逻辑,这里我们希望以字符串长度升序排序
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])
}
// 一切就绪之后,我们就可以把需要进行自定义排序
// 的字符串类型fruits转换为ByLength类型,然后使用
// sort包的Sort方法来排序
func main() {
    fruits := []string{"a", "bb", "ccc","dddd","ee","121212"}
    sort.Sort(ByLength(fruits))
    fmt.Println(fruits)
}

Base64

package main

import base64 "encoding/base64"
import "fmt"
func main() {

    data := "ms~go"

    sEnc := base64.StdEncoding.EncodeToString([]byte(data))
    fmt.Println(sEnc)

    sDec, _ := base64.StdEncoding.DecodeString(sEnc)
    fmt.Println(string(sDec))
    fmt.Println()

    uEnc := base64.URLEncoding.EncodeToString([]byte(data))
    fmt.Println(uEnc)
    uDec, _ := base64.URLEncoding.DecodeString(uEnc)
    fmt.Println(string(uDec))
}

for 循环

package main

import (
    "math/rand"
    "fmt"
)

func main() {

    var i=0

    for i<100 {
        fmt.Println(rand.Intn(0xff))
        i++
    }

}
package main

import (
    "fmt"
)


func main() {

    for i := 0; i <= 9; i++ {
        fmt.Println(i)
    }

}

循环一次

package main

import (
    "fmt"
)

func main() {

    for {
        fmt.Println("for")
        break
    }

}

if

package main

import (
    "math/rand"
    "fmt"
)

func main() {

    var i=0

    for i<100 {
        fmt.Println(rand.Intn(0xff))
        i++

        if(i==2){
            continue
        }

        if(i==10){
            break
        }

    }

}

defer

Defer 用来保证一个函数调用会在程序执行的最后被调用。通常用于资源清理工作。

package main

import "fmt"
import "os"

func main() {

    f := createFile("defer.txt")

    defer closeFile(f)

    writeFile(f)
}
func createFile(p string) *os.File {

    f, err := os.Create(p)

    if err != nil {

        panic(err)

    }

    return f
}

func writeFile(f *os.File) {

    fmt.Fprintln(f, "hello world defer")

}

func closeFile(f *os.File) {
    if f != nil {
        f.Close()
    }
}

Exit

package main

import (
    "os"
    "fmt"
)

func main() {

    var i = 0

    for i < 100 {
        fmt.Println(i)
        if i == 50 {
            os.Exit(0)
        }

        i++
    }

}

if else

可变参数

package main

import "fmt"

func main() {

    sop(123165,564,235235,5234234,54234,51,61,)
}

/**
    可变参数
 */
func sop(args ...int) {

    for i := 0; i < len(args); i++ {
        fmt.Println(args[i])
    }

}

函数作为返回值

package main

import "fmt"

func main() {

    hello := func() {
        println("hello")

    }
    hello()
    //打印类型
    fmt.Printf("%T", hello)
}

panic

package main

import "os"

func main() {
    // 我们使用panic来检查预期不到的错误
    panic("a problem")
    // Panic的通常使用方法就是如果一个函数
    // 返回一个我们不知道怎么处理的错误的
    // 时候,直接终止执行。
    _, err := os.Create("1.txt")
    if err != nil {
        panic(err)
    }
}

键盘输入

package main

import (
    "bufio"
    "os"
    "fmt"
    "strings"
)

func main() {
    // 键盘输入
    scanner := bufio.NewScanner(os.Stdin)
    //循环获取输入
    for scanner.Scan() {
        //打印  转换为大写
        fmt.Println(scanner.Text() + "   ||   " + strings.ToUpper(scanner.Text()))

    }
    //检查错误。文件结束不会被当作一个错误
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "error:", err)
        os.Exit(0)
    }

}

range

package main

import "fmt"

func main() {
    sop(1, 2, 4, 6, 8, 10)

}

func sop(args ...int) {
    for _, i := range args {
        fmt.Println(i)
    }
}
for i, c := range "AB" {
    fmt.Println(i, c)
}

SH1

package main

import (
    "crypto/sha1"
    "fmt"
)

func main() {

    s1 := sha1.New()

    s1.Write([]byte("ms~go"))

    bs := s1.Sum(nil)

    fmt.Printf("%x", bs)

}

结构体

package main
import "fmt"
// 这个person结构体有name和age成员
type person struct {
    name string
    age int
}
func main() {
    // 这个语法创建一个新结构体变量
    fmt.Println(person{"Bob", 20})
    // 可以使用"成员:值"的方式来初始化结构体变量
    fmt.Println(person{name: "Alice", age: 30})
    // 未显式赋值的成员初始值为零值
    fmt.Println(person{name: "Fred"})
    // 可以使用&来获取结构体变量的地址
    fmt.Println(&person{name: "Ann", age: 40})
    // 使用点号(.)来访问结构体成员
    s := person{name: "Sean", age: 50}
    fmt.Println(s.name)
    // 结构体指针也可以使用点号(.)来访问结构体成员
    // Go语言会自动识别出来
    sp := &s
    fmt.Println(sp.age)
    // 结构体成员变量的值是可以改变的
    sp.age = 51
    fmt.Println(sp.age)
}

URL解析

package main
import "fmt"
import "net/url"
import "strings"
func main() {
    // 我们将解析这个URL,它包含了模式,验证信息,
    // 主机,端口,路径,查询参数和查询片段
    s := "postgres://user:pass@host.com:5432/path?k=v#f"
    // 解析URL,并保证没有错误
    u, err := url.Parse(s)
    if err != nil {
        panic(err)
    }
    // 可以直接访问解析后的模式
    fmt.Println(u.Scheme)
    // User包含了所有的验证信息,使用
    // Username和Password来获取单独的信息
    fmt.Println(u.User)
    fmt.Println(u.User.Username())
    p, _ := u.User.Password()
    fmt.Println(p)
    // Host包含了主机名和端口,如果需要可以
    // 手动分解主机名和端口
    fmt.Println(u.Host)
    h := strings.Split(u.Host, ":")
    fmt.Println(h[0])
    fmt.Println(h[1])
    // 这里我们解析出路径和`#`后面的片段
    fmt.Println(u.Path)
    fmt.Println(u.Fragment)
    // 为了得到`k=v`格式的查询参数,使用RawQuery。你可以将
    // 查询参数解析到一个map里面。这个map为字符串作为key,
    // 字符串切片作为value。
    fmt.Println(u.RawQuery)
    m, _ := url.ParseQuery(u.RawQuery)
    fmt.Println(m)
    fmt.Println(m["k"][0])
}

内存分配

package main

import (
    "sync"
    "bytes"
    "fmt"
)

type SyncedBuffer struct {
    lock    sync.Mutex
    bbuffer bytes.Buffer
}

func main() {
    _ = new(SyncedBuffer)
    var _ SyncedBuffer

    var p1 *[]int = new([]int)
    var p2 []int = make([]int,10000)

    fmt.Printf("%p", p1)
    fmt.Printf("%p", p2)

}

自定义类型

package main

import "fmt"

// 自定义类型
type ms string

//结构体
type person struct {
    name ms
}

func main() {

    var p1 = new(person)
    p1.name="ms"
    fmt.Println(p1)

}

类型转换

package main

import "fmt"

func main(){


    var a int = 10
    fmt.Println(a)
    var b float64=float64(a)
    fmt.Println(b)

}

接口

package main

import "fmt"

import "math"

// 这里定义了一个最基本的表示几何形状的方法的接口
type geometry interface {

    area() float64

    perim() float64

}

// 这里我们要让正方形square和圆形circle实现这个接口

type square struct {

    width, height float64

}

type circle struct {

    radius float64

}

// 在Go中实现一个接口,只要实现该接口定义的所有方法即可

// 下面是正方形实现的接口

func (s square) area() float64 {

    return s.width * s.height

}

func (s square) perim() float64 {

    return 2*s.width + 2*s.height

}

// 圆形实现的接口

func (c circle) area() float64 {

    return math.Pi * c.radius * c.radius

}

func (c circle) perim() float64 {

    return 2 * math.Pi * c.radius

}

// 如果一个函数的参数是接口类型,那么我们可以使用命名接口

// 来调用这个函数

// 比如这里的正方形square和圆形circle都实现了接口geometry,

// 那么它们都可以作为这个参数为geometry类型的函数的参数。

// 在measure函数内部,Go知道调用哪个结构体实现的接口方法。

func measure(g geometry) {

    fmt.Println(g)

    fmt.Println(g.area())

    fmt.Println(g.perim())

}

func main() {

    s := square{width: 3, height: 4}

    c := circle{radius: 5}

    // 这里circle和square都实现了geometry接口,所以

    // circle类型变量和square类型变量都可以作为measure

    // 函数的参数

    measure(s)

    measure(c)
}

数组和冒泡

package main

import "fmt"

func main() {

    arr := []int{10, 12, 33, 14, 65}
    for _, i := range arr {
        fmt.Printf("%d  ",i)

    }

    fmt.Println()

    bubblesort(arr)
    for _, i := range arr {
        fmt.Printf("%d  ",i)
    }

}

func bubblesort(n[]int) {
    for i := 0; i < len(n)-1; i++ {
        for j := i + 1; j < len(n); j++ {
            if n[j] < n[i] {
                n[i], n[j] = n[j], n[i]
            }
        }
    }
}

一维数组,二位数组,二维数组的转置

package main

import "fmt"

func main() {

    var a [5]int

    a[0] = 1024 >> 10

    fmt.Printf("%d  \n", a)

    var c = 0
    var b [3][3]int
    var d [3][3]int
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            c++
            b[i][j] = c
        }
    }
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            fmt.Printf("%d  ", b[i][j])
        }
        fmt.Println()
    }

    fmt.Println("----------")

    for i := 0; i < len(b); i++ {
        for j := 0; j < len(b[0]); j++ {
            d[i][j] = b[j][i]
        }
    }

    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            fmt.Printf("%d  ", d[i][j])
        }
        fmt.Println()
    }
}

超时时间

package main

import "time"

func main() {
    c := make(chan int)
    o := make(chan bool)
    go func() {
        for {
            select {
            case v := <-c:
                println(v)
            case <-time.After(5 * time.Second):
                println("timeout")
                o <- true
                break
            }
        }
    }()
    <-o
}

json 编码与解析

package main

import "encoding/json"
import "fmt"

type Person struct {
    Name string
    Age  int
    Sex  bool
}

func main() {
    /*****json转换*****/

    //创建对象
    person := Person{

        "ms~go",
        23,
        true,
    }
    //json编码
    personjson, _ := json.Marshal(person)
    //输出json字符串
    fmt.Println(string(personjson))

    /*****json解析*****/
    strjson := `{"Name":"ms~go","Age":23,"Sex":true}`
    r := &Person{}
    json.Unmarshal([]byte(strjson), &r)
    fmt.Println(r)
    fmt.Println(r.Name)
    fmt.Println(r.Age)
    fmt.Println(r.Sex)

}

查看某个环境变量

package main

import (
    "os"
    "fmt"
)

func main() {


    ANDROID_HOME,AB:=os.LookupEnv("ANDROID_HOME")
    fmt.Println(ANDROID_HOME)
    fmt.Println(AB)

    JAVA_HOME,JB:=os.LookupEnv("JAVA_HOME")
    fmt.Println(JAVA_HOME)
    fmt.Println(JB)

    PATH,PB:=os.LookupEnv("PATH")
    fmt.Println(PATH)
    fmt.Println(PB)

}

执行CMD命令

package main

import "os/exec"

func main() {
    cmdcalc := exec.Command("calc")
    cmdcalc.Start()

    cmdnotepad := exec.Command("notepad")
    cmdnotepad.Start()

    cmdmspaitn := exec.Command("mspaint")
    cmdmspaitn.Start()
}

http get 请求

package main

import (
    "net/http"
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    //http 请求
    resp, _ := http.Get("http://www.baidu.com/")
    //defer 打开
    defer resp.Body.Close()
    //获取请求体
    body, _ := ioutil.ReadAll(resp.Body)
    //打印请求到的数据
    fmt.Println(string(body))
    //创建文件
    os.Create("baidu.html")
    //写入数据
    ioutil.WriteFile("baidu.html", body, 777)

}

goroutine

package main

import (
    "fmt"
    "time"
)

func main() {
    //必须先运行ms和ms1
    //如果先运行for{} 则执行不到 ms() ms1()
    go ms()
    go ms1()
    for {
        fmt.Println("this is main ")
        time.Sleep(time.Second)
    }

}

// 函数1
func ms() {

    for {
        fmt.Println("this is ms")
        time.Sleep(time.Second)
    }
}

//函数2
func ms1() {

    for {
        fmt.Println("this is ms1")
        time.Sleep(time.Second)
    }
}

文件创建

package main

import (
    "os"
    "bufio"
)

func main() {

    // 创建文件
    f, _ := os.Create("hello world.txt")
    //defer关闭文件
    defer f.Close()
    //写入文件 方法1
    f.Write([]byte("hello world "))
    //写入文件 方法2
    f.WriteString("你是我的眼")
    //同步文件
    f.Sync()
    //写入文件方法3
    w := bufio.NewWriter(f)
    //写入数据
    w.WriteString("哈哈哈哈哈哈")
    //刷新
    w.Flush()

}

文件写入

package main

import "io/ioutil"

func main() {

    var str = "File Writer"

    ioutil.WriteFile("fw.txt", []byte(str), 0777)

}

文件读取

package main

import (
    "io/ioutil"
    "fmt"
)

func main() {

    fr, _ := ioutil.ReadFile("fw.txt")
    fmt.Println(string(fr))

}

读取文件的方法速度比较

package main

import (
    "bufio"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "time"
    "net/http"
)

func read0(path string) string {
    f, err := ioutil.ReadFile(path)
    if err != nil {
        fmt.Printf("%s\n", err)
        panic(err)
    }
    return string(f)
}

func read1(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()

    chunks := make([]byte, 1024, 1024)
    buf := make([]byte, 1024)
    for {
        n, err := fi.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if 0 == n {
            break
        }
        chunks = append(chunks, buf[:n]...)
    }
    return string(chunks)
}

func read2(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()
    r := bufio.NewReader(fi)

    chunks := make([]byte, 1024, 1024)

    buf := make([]byte, 1024)
    for {
        n, err := r.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if 0 == n {
            break
        }
        chunks = append(chunks, buf[:n]...)
    }
    return string(chunks)
}

func read3(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()
    fd, err := ioutil.ReadAll(fi)
    return string(fd)
}

func main() {

    str, _ := http.Get("http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jsp?category=%E5%A3%81%E7%BA%B8&tag=%E5%85%A8%E9%83%A8&start=0&len=100000")

    html, _ := ioutil.ReadAll(str.Body)

    ioutil.WriteFile("fw.json", html, 0777)

    file := "fw.json"

    start := time.Now()

    read0(file)
    t0 := time.Now()
    fmt.Printf("Cost time %v\n", t0.Sub(start))

    read1(file)
    t1 := time.Now()
    fmt.Printf("Cost time %v\n", t1.Sub(t0))

    read2(file)
    t2 := time.Now()
    fmt.Printf("Cost time %v\n", t2.Sub(t1))

    read3(file)
    t3 := time.Now()
    fmt.Printf("Cost time %v\n", t3.Sub(t2))

}

递归遍历目录

GO语言获取目录列表用 ioutil.ReadDir(),遍历目录用 filepath.Walk()

web 服务

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler) // each request calls handler
    log.Fatal(http.ListenAndServe("localhost:9512", nil))
}

// handler echoes the Path component of the request URL r.
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "你是我的眼")
}

Go 操作Excel文件

https://github.com/360EntSecGroup-Skylar/excelize

写入文件

package main

import (
    "fmt"

    "strconv"
    "github.com/360EntSecGroup-Skylar/excelize"
)

func main() {

    // 创建XMLS文件
    xlsx := excelize.NewFile()
    //循环写入数据
    for i := 1; i < 1000; i++ {
        //拼接字符串
        //位子
        axis := "B" + strconv.Itoa(i)
        //在指定的位置写入数据
        xlsx.SetCellValue("Sheet1", axis, 1024*i)

    }
    //创建sheet
    index := xlsx.NewSheet("Sheet2")
    //循环写入数据
    for i := 1; i < 1000; i++ {
        axis := "A" + strconv.Itoa(i)
        //写入
        xlsx.SetCellValue("Sheet2", axis, 1024*i)

    }
    //保存
    xlsx.SetActiveSheet(index)
    //保存文件
    err := xlsx.SaveAs("hello.xlsx")
    if err != nil {
        fmt.Println(err)
    }

}

将数字转化为字符串

strconv.Itoa(i)

读取Excel文件

package main

import (
    "fmt"
    "github.com/360EntSecGroup-Skylar/excelize"
    "strconv"
)

func main() {
    xlsx, err := excelize.OpenFile("1.xlsx")
    if err != nil {
        fmt.Println(err)
        return
    }


    for i := 1; i < 100; i++ {
        //读取
        axisa := "A" + strconv.Itoa(i)
        cella := xlsx.GetCellValue("06-08", axisa)
        fmt.Println(cella)

        axisb := "B" + strconv.Itoa(i)
        cellb := xlsx.GetCellValue("06-08", axisb)
        fmt.Println(cellb)
    }

    //读取指定sheet的所有信息
    rows := xlsx.GetRows("06-08")
    for _, row := range rows {
        for _, colCell := range row {
            fmt.Print(colCell, "\t")
        }
        fmt.Println()
    }
}

Excel 写入图片

package main

import (
    "fmt"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"

    "github.com/360EntSecGroup-Skylar/excelize"
    "strconv"
)

func main() {
    xlsx, err := excelize.OpenFile("1.xlsx")
    if err != nil {
        fmt.Println(err)
        return
    }

    for i := 1; i < 200; i++ {

        if (i%23 == 0) {

            xlsx.AddPicture("Sheet1", "A"+strconv.Itoa(i), "hai.png", `{"x_scale": 0.5, "y_scale": 0.5}`)

        }
    }

    //xlsx.AddPicture("Sheet1", "A22", "hai.png", `{"x_scale": 0.5, "y_scale": 0.5}`)

    //xlsx.AddPicture("Sheet1", "F1", "hai.png", `{"x_scale": 0.5, "y_scale": 0.5}`)
    //
    //
    //xlsx.AddPicture("Sheet1", "H2", "hai.png", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)

    err = xlsx.Save()
    if err != nil {
        fmt.Println(err)
    }
}

MP3播放

package main

import (
    "io/ioutil"

    "github.com/hajimehoshi/oto"
    "github.com/tosone/minimp3"
)

func main() {
    var file, _ = ioutil.ReadFile("杨坤 - 那一天.mp3")
    dec, data, _ := minimp3.DecodeFull(file)

    player, _ := oto.NewPlayer(dec.SampleRate, dec.Channels, 2, 1024*8)
    player.Write(data)
}

文件切割

package main

import (
    "math"
    "os"
    "strconv"
)

const chunkSize int64 = 1024 * 1024 * 64

func main() {

    // 获取文件的信息
    fileInfo, _ := os.Stat("27_运算符(上).avi")
    //计算每一个区块的大小
    num := int(math.Ceil(float64(fileInfo.Size()) / float64(chunkSize)))
    //打开文件
    fi, _ := os.OpenFile("27_运算符(上).avi", os.O_RDONLY, os.ModePerm)
    //
    b := make([]byte, chunkSize)
    //
    var i int64 = 1
    //
    for ; i <= int64(num); i++ {
        //移动指针
        fi.Seek((i-1)*(chunkSize), 0)

        if len(b) > int((fileInfo.Size() - (i-1)*chunkSize)) {
            //分配内存
            b = make([]byte, fileInfo.Size()-(i-1)*chunkSize)
        }

        //
        fi.Read(b)
        // 创建块的文件
        f, _ := os.OpenFile(strconv.Itoa(int(i))+".db", os.O_CREATE|os.O_WRONLY, os.ModePerm)
        //写入块文件
        f.Write(b)
        //关闭文件
        f.Close()
    }

}

文件合并

package main

import (
    "os"
    "fmt"
    "strconv"
    "io/ioutil"
)

func main() {

    fii, _ := os.OpenFile("1.avi", os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)

    for i := 1; i <= 33; i++ {
        f, err := os.OpenFile(strconv.Itoa(int(i))+".db", os.O_RDONLY, os.ModePerm)
        if err != nil {
            fmt.Println(err)
            return
        }
        b, _ := ioutil.ReadAll(f)
        fii.Write(b)
        f.Close()
    }

}

http 请求

package main

import (
    "fmt"
    "net/http"
    "io"
    "os"
    "sync/atomic"
    "runtime"
    "time"
)

func main() {

    //生成client 参数为默认
    client := &http.Client{}

    //生成要访问的url
    url := "http://www.baidu.com"

    //提交请求
    reqest, _ := http.NewRequest("GET", url, nil)

    //处理返回结果
    response, _ := client.Do(reqest)

    //将结果定位到标准输出 也可以直接打印出来 或者定位到其他地方进行相应的处理
    stdout := os.Stdout

    //输出请求体
    _, _ = io.Copy(stdout, response.Body)

    //返回的状态码
    status := response.StatusCode

    //打印输出状态
    fmt.Println(status)

}

原子计数器

package main

import "fmt"
import "time"
import "sync/atomic"
import "runtime"

func main() {
    // 我们使用一个无符号整型来代表一个永远为正整数的counter
    var ops uint64 = 0
    // 为了模拟并行更新,我们使用50个协程来每隔1毫秒来
    // 增加一下counter值,注意这里的50协程里面的for循环,
    // 也就是说如果主协程不退出,这些协程将永远运行下去
    // 所以这个程序每次输出的值有可能不一样
    for i := 0; i < 50; i++ {
        go func() {
            for {
                // 为了能够保证counter值增加的原子性,我们使用
                // atomic包中的AddUint64方法,将counter的地址和
                // 需要增加的值传递给函数即可
                atomic.AddUint64(&ops, 1)
                // 允许其他的协程来处理
                runtime.Gosched()
            }
        }()
    }
    //等待1秒中,让协程有时间运行一段时间
    time.Sleep(time.Second)
    // 为了能够在counter仍被其他协程更新值的同时安全访问counter值,
    // 我们获取一个当前counter值的拷贝,这里就是opsFinal,需要把
    // ops的地址传递给函数`LoadUint64`
    opsFinal := atomic.LoadUint64(&ops)
    fmt.Println("ops:", opsFinal)
}

信号

package main
import "fmt"
import "os"
import "os/signal"
import "syscall"
func main() {
    // Go信号通知通过向一个channel发送``os.Signal`来实现。
    // 我们将创建一个channel来接受这些通知,同时我们还用
    // 一个channel来在程序可以退出的时候通知我们
    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)
    // `signal.Notify`在给定的channel上面注册该channel
    // 可以接受的信号
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    // 这个goroutine阻塞等待信号的到来,当信号到来的时候,
    // 输出该信号,然后通知程序可以结束了
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
    }()
    // 程序将等待接受信号,然后退出
    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}

chan

package main

import (
    "fmt"
)

func main() {

    str1 := make(chan int, 2)
    str2 := make(chan int, 2)

    str1 <- 100
    str2 <- 0xff

    c1 := <-str1
    c2 := <-str2

    fmt.Printf("%d   %d", c1, c2)
}

账单的写入

package main

import (
    "fmt"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"

    "github.com/360EntSecGroup-Skylar/excelize"
    "strconv"
    "io/ioutil"
)

var i = 1
var xlsx, _ = excelize.OpenFile("1.xlsx")

func main() {

    readDir("F:\\初见文件\\初见\\支付测试")

    xlsx.Save()

}

func readDir(dirPath string) {
    flist, e := ioutil.ReadDir(dirPath)

    if e != nil {
        fmt.Println("Read file error")
        return
    }

    for _, f := range flist {
        if f.IsDir() {

            readDir(dirPath + "/" + f.Name())
        } else {
            xlsx.AddPicture("Sheet1", "A"+strconv.Itoa(i), dirPath+"/"+f.Name(), `{"x_scale": 0.5, "y_scale": 0.5}`)
            i += 49
        }

    }
}

文件重命名

// 文件重命名
syscall.Rename("新建文本文档.txt","ms.txt")

环境变量

//获取环境变量
fs := syscall.Environ()

//循环输出
for i = 0; i < len(fs); i++ {
    fmt.Println(fs[i])
}

删除文件

os.Remove("ms2.txt")

连接MySQL

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "root:2018@/ms")//对应数据库的用户名和密码
    defer db.Close()
    if err != nil {
        panic(err)
    } else {
        fmt.Println("success")
    }
    rows, err := db.Query("SELECT * from tb_user ")
    if err != nil {
        panic(err)
        return
    }
    for rows.Next() {
        var name int
        err = rows.Scan(&name)
        if err != nil {
            panic(err)
        }
        fmt.Println(name)
    }
}

Mysql 查询

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, _ := sql.Open("mysql", "root:2018@/ms")

    defer db.Close()

    rows, _ := db.Query("select * from tb_user;")

    defer rows.Close()

    cloumns, _ := rows.Columns()

    values := make([]sql.RawBytes, len(cloumns))

    scanArgs := make([]interface{}, len(values))

    for i := range values {
        scanArgs[i] = &values[i]
    }

    for rows.Next() {

        rows.Scan(scanArgs...)

        var value string

        for i, col := range values {

            if col == nil {

                value = "NULL"

            } else {

                value = string(col)

            }

            fmt.Println(cloumns[i], " --- ", value)
        }

    }

}

增删改

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, _ := sql.Open("mysql", "root:2018@/ms")

    defer db.Close()

    stmt, _ := db.Prepare("INSERT INTO ms VALUES ('MS-1GOGOGO')")

    stmt.Exec()

}

正则表达式

package main
import "bytes"
import "fmt"
import "regexp"
func main() {
    // 测试模式是否匹配字符串,括号里面的意思是
    // 至少有一个a-z之间的字符存在
    match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
    fmt.Println(match)
    // 上面我们直接使用了字符串匹配的正则表达式,
    // 但是对于其他的正则匹配任务,你需要使用
    // `Compile`来使用一个优化过的正则对象
    r, _ := regexp.Compile("p([a-z]+)ch")
    // 正则结构体对象有很多方法可以使用,比如上面的例子
    // 也可以像下面这么写
    fmt.Println(r.MatchString("peach"))
    // 这个方法检测字符串参数是否存在正则所约束的匹配
    fmt.Println(r.FindString("peach punch"))
    // 这个方法查找第一次匹配的索引,并返回匹配字符串
    // 的起始索引和结束索引,而不是匹配的字符串
    fmt.Println(r.FindStringIndex("peach punch"))
    // 这个方法返回全局匹配的字符串和局部匹配的字符,比如
    // 这里会返回匹配`p([a-z]+)ch`的字符串
    // 和匹配`([a-z]+)`的字符串
    fmt.Println(r.FindStringSubmatch("peach punch"))
    // 和上面的方法一样,不同的是返回全局匹配和局部匹配的
    // 起始索引和结束索引
    fmt.Println(r.FindStringSubmatchIndex("peach punch"))
    // 这个方法返回所有正则匹配的字符,不仅仅是第一个
    fmt.Println(r.FindAllString("peach punch pinch", -1))
    // 这个方法返回所有全局匹配和局部匹配的字符串起始索引
    // 和结束索引
    fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))
    // 为这个方法提供一个正整数参数来限制匹配数量
    fmt.Println(r.FindAllString("peach punch pinch", 2))

    //上面我们都是用了诸如`MatchString`这样的方法,其实
    // 我们也可以使用`[]byte`作为参数,并且使用`Match`
    // 这样的方法名
    fmt.Println(r.Match([]byte("peach")))
    // 当使用正则表达式来创建常量的时候,你可以使用`MustCompile`
    // 因为`Compile`返回两个值
    r = regexp.MustCompile("p([a-z]+)ch")
    fmt.Println(r)
    // regexp包也可以用来将字符串的一部分替换为其他的值
    fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
    // `Func`变量可以让你将所有匹配的字符串都经过该函数处理
    // 转变为所需要的值
    in := []byte("a peach")
    out := r.ReplaceAllFunc(in, bytes.ToUpper)
    fmt.Println(string(out))
}

闭包

package main

import "fmt"

// 这个"intSeq"函数返回另外一个在intSeq内部定义的匿名函数,  
// 这个返回的匿名函数包住了变量i,从而形成了一个闭包  
func intSeq() func() int {
    i := 0
    return func() int {
        i += 1
        return i
    }
}
func main() {
    // 我们调用intSeq函数,并且把结果赋值给一个函数nextInt,  
    // 这个nextInt函数拥有自己的i变量,这个变量每次调用都被更新。  
    // 这里i的初始值是由intSeq调用的时候决定的。  
    nextInt := intSeq()
    // 调用几次nextInt,看看闭包的效果  
    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())
    // 为了确认闭包的状态是独立于intSeq函数的,再创建一个。  
    newInts := intSeq()
    fmt.Println(newInts())
}

sync

package main

import (
    "sync"
    "time"
)

var m *sync.RWMutex

var val = 0

func main() {

    m = new(sync.RWMutex)

    go read(1)

    go write(2)

    go read(3)

    time.Sleep(time.Second * 2)

}
func read(i int) {

    m.RLock()

    println("val: ", val)

    m.RUnlock()
}
func write(i int) {

    m.Lock()

    val = 10

    m.Unlock()
}

创建文件夹

package main

import "os"

func main() {
    os.Mkdir("hello", 0777)
}

创建1024个文件夹,然后在删除

package main

import (
    "os"
    "strconv"
    "time"
)

func main() {
    for i := 0; i < 1024; i++ {
        os.Mkdir("hello"+strconv.Itoa(i), 0777)
    }

    time.Sleep(time.Second * 30)

    for i := 0; i < 1024; i++ {
        os.Remove("hello" + strconv.Itoa(i))
    }
}

简单的爬虫(抓取搜狗图片)

package main

import (
    "net/http"
    "strconv"
    "io/ioutil"
    "os"
    "fmt"
)

var start = 0

var len = start + 10

func main() {

    for {
        var url = "http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jsp?category=%E5%A3%81%E7%BA%B8&tag=%E5%85%A8%E9%83%A8&start=" + strconv.Itoa(start) + "&len=" + strconv.Itoa(len)
        fmt.Println(url)
        res, _ := http.Get(url)
        reader, _ := ioutil.ReadAll(res.Body)
        var filename = strconv.Itoa(start) + ".json"
        os.Create(filename)
        ioutil.WriteFile(filename, reader, 0777)
        start = len
        len = start + 10
        if len > 1024 {
            break
        }

    }
}

生成RSA 公钥和私钥

package main

import (
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "crypto/rand"
    "flag"
    "log"
    "os"
)

func main() {
    var bits int
    flag.IntVar(&bits, "b", 2048, "密钥长度,默认为1024位")
    if err := GenRsaKey(bits); err != nil {
        log.Fatal("密钥文件生成失败!")
    }
    log.Println("密钥文件生成成功!")
}

func GenRsaKey(bits int) error {
    // 生成私钥文件
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
        return err
    }
    derStream := x509.MarshalPKCS1PrivateKey(privateKey)
    block := &pem.Block{
        Type:  "私钥",
        Bytes: derStream,
    }
    file, err := os.Create("private.pem")
    if err != nil {
        return err
    }
    err = pem.Encode(file, block)
    if err != nil {
        return err
    }
    // 生成公钥文件
    publicKey := &privateKey.PublicKey
    derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
    if err != nil {
        return err
    }
    block = &pem.Block{
        Type:  "公钥",
        Bytes: derPkix,
    }
    file, err = os.Create("public.pem")
    if err != nil {
        return err
    }
    err = pem.Encode(file, block)
    if err != nil {
        return err
    }
    return nil
}

测试RSA

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    _ "encoding/base64"
    "encoding/pem"
    "errors"
    "flag"
    "fmt"
    "io/ioutil"
    "os"
)

var decrypted string
var privateKey, publicKey []byte

func init() {
    var err error
    flag.StringVar(&decrypted, "d", "", "加密过的数据")
    flag.Parse()
    publicKey, err = ioutil.ReadFile("public.pem")
    if err != nil {
        os.Exit(-1)
    }
    privateKey, err = ioutil.ReadFile("private.pem")
    if err != nil {
        os.Exit(-1)
    }
}

func main() {
    var data []byte
    var err error
    data, err = RsaEncrypt([]byte("ms~go"))
    if err != nil {
        panic(err)
    }
    origData, err := RsaDecrypt(data)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(origData))
}

// 加密
func RsaEncrypt(origData []byte) ([]byte, error) {
    block, _ := pem.Decode(publicKey)
    if block == nil {
        return nil, errors.New("public key error")
    }
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    pub := pubInterface.(*rsa.PublicKey)
    return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

// 解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
    block, _ := pem.Decode(privateKey)
    if block == nil {
        return nil, errors.New("private key error!")
    }
    priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}

init 函数

package main

import "fmt"

func init() {
    fmt.Println("Hello INIT")
}

func main() {

    fmt.Println("main")
}

init 优先执行main函数

单例模式

package main

import (
    "fmt"
)

var m *Manager

func GetInstance() *Manager {
    if m == nil {
        m = &Manager{}
    }
    return m
}

type Manager struct{}

func (p Manager) Manage() {
    fmt.Println("manage...")
}

func main() {

    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())

}

单例加锁

package main

import (
    "fmt"
    "sync"
    "time"
)

var m *Manager
var lock *sync.Mutex = &sync.Mutex{}

func GetInstance() *Manager {
    lock.Lock()
    defer lock.Unlock()
    if m == nil {
        m = &Manager{}
    }
    return m
}

type Manager struct{}

func (p Manager) Manage() {
    fmt.Println("manage...")
}
func main() {

    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    time.Sleep(time.Second)

}

双重锁机制来提高效率

package main

import (
    "fmt"
    "sync"
    "time"
)

var m *Manager
var lock *sync.Mutex = &sync.Mutex {}

func GetInstance() *Manager {
    if m == nil {
        lock.Lock()
        defer lock.Unlock()
        if m == nil {
            m = &Manager {}
        }
    }

    return m
}

type Manager struct {}

func (p Manager) Manage() {
    fmt.Println("manage...")
}
func main() {

    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    time.Sleep(time.Second)

}

sync.Once

package main

import (
    "fmt"
    "sync"
    "time"
)

var m *Manager
var once sync.Once

func GetInstance() *Manager {
    once.Do(func() {
        m = &Manager{}
    })
    return m
}

type Manager struct{}

func (p Manager) Manage() {
    fmt.Println("manage...")
}
func main() {

    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    go func() { fmt.Printf("%p\n", GetInstance()) }()
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    fmt.Printf("%p\n", GetInstance())
    time.Sleep(time.Second)

}

文件拷贝

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    CopyFile("1private.pem", "private.pem") // os.Args[1]为目标文件,os.Args[2]为源文件
    fmt.Println("复制完成")
}
func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }
    defer src.Close()
    dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
    if err != nil {
        return
    }
    defer dst.Close()
    return io.Copy(dst, src)
}

查看原文: Go 语言学习案例

  • heavypanda
  • silverfrog
  • smallfrog
  • ticklishmouse
  • crazybird
  • bigpanda
  • lazymouse342