Go 语言学习案例

GOLang 笔记

2018/1/1 12:12:17


环境搭建

Go软件下载地址

安装

推荐IDE GoLand

安装

IDE 注册服务器

http://btsha.com:41017

IDE 配置

API 地址

https://studygolang.com/pkgdoc

环境变量介绍

GOPATH

工程目录

GOROOT

Go软件的安装目录

经典程序 Hello World


// 必须为main
package main

import "fmt"

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

25关键字

breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar

36 个预定义标识符

appendboolbytecapclosecomplexcomplex64complex128uint16
copyfalsefloat32float64imagintint8int16uint32
int32int64iotalenmakenewnilpanicuint64
printprintlnrealrecoverstringtrueuintuint8uintptr

变量

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)
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值