func main(){
var num []int = []int{0,0,0,0,0}
fmt.Println(num)
modifyArray(num)
fmt.Println(num)
}
func modifyArray(ar []int){//传递的只是切片,底层还是指向同一个数组
ar[1] = 22
fmt.Printf("ar[1] : %d\n",ar[1])
}
func main(){
var num [5]int
fmt.Println(num)
modifyArray(num)
fmt.Println(num)
}
func modifyArray(ar [5]int){//数组传递参数是值拷贝
ar[1] = 22
fmt.Printf("ar[1] : %d\n",ar[1])
}
var p *int
//fmt.Println("p:",*p) 错误,panic: runtime error: invalid memory address or nil pointer dereference
fmt.Println("p:",p)
fmt.Printf("p:%x\n",p)
fmt.Printf("p:",p)
var m map[string]int
m["hello"] = 10
fmt.Println(m["hello"])
var m map[string]int
m = make(map[string]int)
m["hello"] = 10
fmt.Println(m["hello"])
var m map[string]int = map[string]int{}
m["hello"] = 10
fmt.Println(m["hello"])
5.Type switch(类型switch)与Type assertions(类型断言)
func main(){
var i int = 10
TypeOf(i)
var d float64
TypeOf(d)
var value interface{}
value = "abcdefg"
//返回的是值和时候发生错误的bool变量
str, ok := value.(string)//value必须为接口类型,断言是否是string类型
if ok {
fmt.Printf("string value is: %q\n", str)
} else {
fmt.Printf("value is not a string\n")
}
}
func TypeOf(a interface{}){
//返回的是类型
switch t := a.(type){ //类型判断,a必须为接口类型, (t := a.(type)放在switch外为什么不行?)
case int:
fmt.Printf("%d is %T\n",a,t)
break;
default:
fmt.Printf("type : %T\n",t)
}
}
6.闭包
func intSeq()func()int{
i := 0
return func()int{
i++
return i
}
}
func main(){
intNext := intSeq()
fmt.Println(intNext())
fmt.Println(intNext())
fmt.Println(intNext())
numNext := intSeq()
fmt.Println(numNext())
fmt.Println(numNext())
}
运行结果:
17.json与对象互转(json的key为变量名)
import "fmt"
import "encoding/json"
type Position struct{
X,Y,Z int
}
type Person struct{
Name,Sex string
Age int
Posi Position
}
func main(){
position := Position{10,20,30}
person := Person{"zhang","male",18,position}
position2 := Position{40,50,60}
person2 := Person{"li","female",19,position2}
//对象转json
var slice = make([]Person ,2)
slice[0] = person
slice[1] = person2
fmt.Printf("slice = %v\n",slice)
data,err := json.Marshal(slice)
if err != nil{
fmt.Printf("err = %v\n",err)
return
}
fmt.Printf("data = %s\n",data)
//json转对象
var dslice = make([]Person,1)
err = json.Unmarshal(data,&dslice)
if err != nil{
fmt.Printf("err = %v\n",err)
return
}
fmt.Printf("dslice = %v\n",dslice)
}
运行结果:
slice = [{zhang male 18 {10 20 30}} {li female 19 {40 50 60}}]8.json与对象互转(json的key自定义)
import "fmt"
import "encoding/json"
type Position struct{
X int `json:"x"`
Y int `json:"y"`
Z int `json:"z"`
}
type Person struct{
Name string `json:"name"`
Sex string `json:"sex"`
Age int `json:"age"`
Posi Position `json:"position"`
}
func main(){
position := Position{10,20,30}
person := Person{"zhang","male",18,position}
position2 := Position{40,50,60}
person2 := Person{"li","female",19,position2}
//对象转json
var slice = make([]Person ,2)
slice[0] = person
slice[1] = person2
fmt.Printf("slice = %v\n",slice)
data,err := json.Marshal(slice)
if err != nil{
fmt.Printf("err = %v\n",err)
return
}
fmt.Printf("data = %s\n",data)
//json转对象
var dslice = make([]Person,1)
err = json.Unmarshal(data,&dslice)
if err != nil{
fmt.Printf("err = %v\n",err)
return
}
fmt.Printf("dslice = %v\n",dslice)
}
运行结果:
slice = [{zhang male 18 {10 20 30}} {li female 19 {40 50 60}}]9.Go工作池
import (
"fmt"
"time"
)
func worker(id int,jobs <-chan int,results chan<- int){
for job := range jobs {
fmt.Println("worker",id,"start job",job)
time.Sleep(time.Second)
fmt.Println("worker",id,"finish job",job)
results <- job
}
}
func main(){
jobs := make(chan int ,100)
results := make(chan int ,100)
for i := 1 ;i <= 3; i++{
go worker(i,jobs,results)
}
for i := 1;i<=5;i++{
jobs <- i
}
close(jobs)
for i := 1;i<=5;i++{
fmt.Println(<- results)
}
//如果使用range循环results,如何停止(关闭)results channel ?
}
运行结果:
worker 3 start job 1其主要原因是,原子操作由底层硬件支持,而锁则由操作系统提供的API实现。若实现相同的功能,前者通常会更有效率。)
import "fmt"
import "sync/atomic"
func main(){
var ops uint64 = 0
var opt uint64 = 0
var count = make(chan int ,50)
for i:=0;i<50;i++{
go func(){
for j:=0;j<1000;j++{
atomic.AddUint64(&ops,1) //原子操作
opt++ //非原子操作
}
count<-i
}()
}
for i:=0;i<50;i++{
<-count
}
fmt.Println("ops:",ops,"opt:",opt)
}
运行结果:
ops: 50000 opt: 21176)
import "fmt"
import "math/rand"
import "sync"
import "sync/atomic"
import "time"
func main(){
var state = make(map[int]int)
var mutex = &sync.Mutex{}
var readOps uint64 = 0
var writeOps uint64 = 0
for i:=0;i<100;i++{
go func(){
total := 0
for{
key := rand.Intn(5)
mutex.Lock() //在并发环境中,对map读写操作如果不加锁就会报错
total += state[key]
mutex.Unlock() //在并发环境中,对map读写操作如果不加锁就会报错
atomic.AddUint64(&readOps,1)
time.Sleep(time.Millisecond)
}
}()
}
for w:=0;w<10;w++{
go func(){
for{
key := rand.Intn(5)
val := rand.Intn(100)
mutex.Lock() //在并发环境中,对map读写操作如果不加锁就会报错
state[key] = val
mutex.Unlock() //在并发环境中,对map读写操作如果不加锁就会报错
atomic.AddUint64(&writeOps,1)
time.Sleep(time.Millisecond)
}
}()
}
time.Sleep(time.Second)
readOpsFinal := atomic.LoadUint64(&readOps)
fmt.Println("readOps:",readOpsFinal)
writeOpsFinal := atomic.LoadUint64(&writeOps)
fmt.Println("writeOps:",writeOpsFinal)
mutex.Lock()
fmt.Println("state:",state)
mutex.Unlock()
}
运行结果:
readOps: 9296312.chan实现线程安全(goroutine和通道的内置同步功能来实现共享状态的访问)
import "fmt"
import "time"
import "sync/atomic"
import "math/rand"
type readOps struct{
key int
resp chan int
}
type writeOps struct{
key int
val int
resp chan bool
}
func main(){
reads := make(chan *readOps)
writes := make(chan *writeOps)
var readNum uint64 = 0
var writeNum uint64 = 0
for i:=0;i<100;i++{
go func(){
state := make(map[int]int)
for{
select{
case r := <- reads:
r.resp <- state[r.key]
break
case d := <- writes:
state[d.key] = d.val
d.resp <- true
break
}
}
}()
}
for i:=0;i<100;i++{
go func(){
for{
read := &readOps{
key:rand.Intn(5),
resp:make(chan int)}//}不能换行
reads <- read
<- read.resp
atomic.AddUint64(&readNum,1)
time.Sleep(time.Millisecond)
}
}()
}
for i:=0;i<10;i++{
go func(){
for{
write := &writeOps{
key : rand.Intn(5),
val : rand.Intn(100),
resp: make(chan bool)}//}不能换行
writes <- write
<- write.resp
atomic.AddUint64(&writeNum,1)
time.Sleep(time.Millisecond)
}
}()
}
time.Sleep(time.Second)
readTemp := atomic.LoadUint64(&readNum)
fmt.Println("readNum",readTemp)
writeTemp := atomic.LoadUint64(&writeNum)
fmt.Println("writeNum",writeTemp)
}
运行结果:
readNum 90960(自定义函数进行排序,我们需要一个相应的类型,该类型需要实现sort.Interface接口的Len、Less、Swap方法)
import "fmt"
import "sort"
type ByLenth []string
func (b ByLenth) Len() int{//长度
return len(b)
}
func (b ByLenth) Less(i,j int) bool{//自定义排序逻辑
return len(b[i]) < len(b[j])
}
func (b ByLenth) Swap(i,j int){//交换
b[i],b[j] = b[j],b[i]
}
func main(){
b := ByLenth{"abcdef","123","wwww"}
sort.Sort(b)
fmt.Println(b)
}
运行结果:
[123 wwww abcdef](defer:延迟操作,io:文件操作)
import "fmt"
import "os"
import "io/ioutil"
func main(){
//write
//f := createFile("defer-file.txt")
//defer closeFile(f)
//writeFile(f)
//read
f := openFile("defer-file.txt")
defer closeFile(f)
readFile(f)
}
func createFile(p string) *os.File{
fmt.Println("creating")
f,err := os.Create(p)
if err != nil{
panic(err)
}
return f
}
func openFile(p string) *os.File{
fmt.Println("creating")
f,err := os.Open(p)
if err != nil{
panic(err)
}
return f
}
func writeFile(f *os.File){
fmt.Println("writing")
fmt.Fprintln(f,"data...")
}
func readFile(f *os.File){
fmt.Println("reading")
b,err := ioutil.ReadAll(f)
if err != nil{
panic(err)
}
fmt.Println(string(b))
}
func closeFile(f *os.File){
fmt.Println("closing")
f.Close()
}
运行结果:
creating15.字符串集合函数
import "fmt"
import "strings"
func Index(vs []string,s string) int{
for i,v := range vs{
if v == s {
return i
}
}
return -1
}
func Include(vs []string,s string) bool{
return Index(vs,s) >= 0
}
func Any(vs []string,f func (s string) bool)bool{
for _,v := range vs{
if f(v){
return true
}
}
return false
}
func All(vs []string,f func(s string)bool) bool{
for _,v := range vs{
if !f(v){
return false
}
}
return true
}
func Filter(vs []string,f func(s string)bool) []string{
tmp := make([]string,0)
for _,v := range vs{
if f(v){
tmp = append(tmp,v)
}
}
return tmp
}
func Map(vs []string,f func(s string)string) []string{
tmp := make([]string,len(vs))
for i,v := range vs{
tmp[i] = f(v)
}
return tmp
}
func main(){
var strs = []string{"peach","apple","android","pear","wa"}
fmt.Println(Index(strs,"android"))
fmt.Println(Index(strs,"Android"))
fmt.Println(Include(strs,"android"))
fmt.Println(Include(strs,"Android"))
fmt.Println(Any(strs,func (s string) bool{
return strings.HasPrefix(s,"a")
}))
fmt.Println(Any(strs,func (s string) bool{
return strings.HasPrefix(s,"A")
}))
fmt.Println(All(strs,func (s string) bool{
return strings.HasPrefix(s,"a")
}))
fmt.Println(All(strs,func (s string) bool{
return strings.HasPrefix(s,"A")
}))
fmt.Println(Filter(strs,func (s string)bool{
return strings.Contains(s,"a")
}))
fmt.Println(Filter(strs,func (s string)bool{
return strings.Contains(s,"A")
}))
fmt.Println(Map(strs,strings.ToUpper))
}
运行结果:
216.math/rand随机数
import "math/rand"
import "fmt"
import "time"
func main(){
//rand.Float64() 返回一个64位浮点数 f,0.0 <= f < 1.0
for i:=0;i<10;i++{
//rand.Seed(time.Now().Unix())//秒(循环10次,每次获取的秒都是一样,所以生成的随机数也一样)
rand.Seed(time.Now().UnixNano())//纳秒(循环10次,每次获取的纳秒都是不一样的,所以生成的随机数都是不一样的)
//如果设置的种子是一样的话,每次生成的随机数就是一样的,
//如果不设置种子,每次生成的随机数也是不一样的
fmt.Println(rand.Intn(100))
}
}
运行结果:
Unix():
运行结果:
2017-12-20 10:24:35.370743684 +0800 CST m=+0.0001655262009-11-17 20:34:58.651387237 +0000 UTCNovember17203458651387237UTCTuesdaytruefalsefalse70901h49m36.719356447s70901.82686648794.254109611989274e+062.5524657671935645e+082552465767193564472017-12-20 02:24:35.370743684 +0000 UTC2001-10-16 14:45:21.93203079 +0000 UTC18.epoch示例
import "fmt"
import "time"
func main(){
now := time.Now()
secs := now.Unix()
nanos := now.UnixNano()
fmt.Println(now)
millis := nanos / 1000000
fmt.Println(secs)
fmt.Println(millis)
fmt.Println(nanos)
fmt.Println(time.Unix(secs,0))
fmt.Println(time.Unix(0,nanos))
}
运行结果:
2017-12-20 10:31:42.75317838 +0800 CST m=+0.00016043619.URL解析
import "fmt"
import "net"
import "net/url"
func main(){
//s := "postgres://user:[email protected]:5432/path?k=v#f"
s := "scheme://user:pass@host:port/path?query=fragment1#fragment2"
u,err := url.Parse(s)
if err != nil{
panic(err)
}
fmt.Println(u.Scheme)
fmt.Println(u.User)
fmt.Println(u.User.Username())
p,_ := u.User.Password()
fmt.Println(p)
fmt.Println(u.Host)
host,port,_ := net.SplitHostPort(u.Host)
fmt.Println(host)
fmt.Println(port)
fmt.Println(u.Path)
fmt.Println(u.Fragment)
fmt.Println(u.RawQuery)
m,_ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
fmt.Println(m["query"][0])
}
运行结果:
scheme20.sha1哈希值([]byte)
import "crypto/sha1"
import "fmt"
func main(){
s := "this is sha1"
h := sha1.New()
h.Write([]byte(s))
bs := h.Sum(nil)
fmt.Println(s)
fmt.Printf("%x\n",bs)
}
运行结果:
this is sha121.sha1哈希值(File)
import "crypto/sha1"
import "fmt"
import "os"
import "io"
func main(){
file,err := os.Open("defer-file.txt")
if err != nil {
return
}
defer file.Close()
h := sha1.New()
_,erro := io.Copy(h,file)
if erro != nil{
return
}
fmt.Printf("%x\n",h.Sum(nil))
}
运行结果:
cc9983a1d0f02dc9281924ccd6ecf6cebfee047722.base64编码/解码
import b64 "encoding/base64"
import "fmt"
func main(){
data := "abc123!?$*&()'-=@~"
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)
sDec,_ := b64.StdEncoding.DecodeString(sEnc)
fmt.Println(string(sDec))
uEnc := b64.URLEncoding.EncodeToString([]byte(data))
fmt.Println(uEnc)
uDec,_ := b64.URLEncoding.DecodeString(uEnc)
fmt.Println(string(uDec))
}
运行结果:
YWJjMTIzIT8kKiYoKSctPUB+)
import "fmt"
import "io/ioutil"
import "os"
import "io"
import "bufio"
func check(e error){
if e != nil{
panic(e)
}
}
var path = "defer-file.txt"
//文件内容:
/**
data...abcdefghigklmn
abc
*/
func main(){
//readFile()
//readAll()
//read()
//readNoBuf()
readBuf()
}
func readBuf(){
fi,err := os.Open(path)
check(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 == io.EOF{//先检测err是否是EOF,是说明已经结束
break
}
check(err)
chunks = append(chunks,buf[:n]...)
}
fmt.Println(string(chunks))
}
func readNoBuf(){
fi,err := os.Open(path)
check(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]...)
}
fmt.Println(string(chunks))
}
func read(){
f,err := os.Open(path)
check(err)
bys := make([]byte,5)
n,err := f.Read(bys)//直接读取,只读取5个字节
check(err)
fmt.Printf("%d bytes : %s\n",n,string(bys)) //5 bytes : data.
o2,err := f.Seek(6,0)
check(err)
bys2 := make([]byte,2)
//函数就是从读取器中读取数据放到我们的buf中,限定了最小的读取字节数,如果我们读取的数据小于最小读取 器,譬如你设定min的值是8,但是你读取的数据字节数是5就会返回一个`io.ErrUnexpectedEOF`,如果大于就会返回`io.ErrShortBuffer`,读取完毕会有`io.EOF`~~
n2,err := io.ReadAtLeast(f,bys2,2)
check(err)
fmt.Printf("%d bytes @ %d : %s\n",n2,o2,string(bys2))//2 bytes @ 6 : .a
_,err = f.Seek(0,0)
check(err)
r3 := bufio.NewReader(f)//封装缓存读取
//// Peek 返回缓存的一个切片,该切片引用缓存中前 n 字节数据
// 该操作不会将数据读出,只是引用
// 引用的数据在下一次读取操作之前是有效的
// 如果引用的数据长度小于 n,则返回一个错误信息
// 如果 n 大于缓存的总大小,则返回 ErrBufferFull
// 通过 Peek 的返回值,可以修改缓存中的数据
// 但是不能修改底层 io.Reader 中的数据
bys3,err := r3.Peek(5)
check(err)
fmt.Printf("5 bytes: %s\n",string(bys3))//5 bytes: data.
f.Close()
}
func readAll(){
f,err := os.Open(path)
check(err)
bys,err := ioutil.ReadAll(f)//速度快(系统封装好的总比自己写的速度要快)
check(err)
fmt.Println(string(bys))
}
func readFile(){
data,err := ioutil.ReadFile("defer-file.txt")//速度较快(系统封装好的总比自己写的速度要快)
check(err)
fmt.Println(string(data))
}
24.文件写入
(//读文件使用os.Open()//写文件使用os.OpenFile())
import "fmt"
import "io/ioutil"
import "os"
import "io"
import "bufio"
func check(e error){
if e != nil{
panic(e)
}
}
/**
*判断文件是否存在,存在返回true,不存在返回false
*/
func checkFileIsExist(file string)bool{
if _,err := os.Stat(file);os.IsNotExist(err){
return false
}
return true
}
var path = "defer-file.txt"
var content = "hello world...\n"
//io,ioutil,File,Writer
func main(){
//writeFile()
//writeString()
//writeNoBuf()
writeBuf()
}
func writeBuf(){
f,err := os.Create(path)
check(err)
defer f.Close()
w := bufio.NewWriter(f)
n,err := w.WriteString(content)
check(err)
fmt.Printf("write %d bytes\n",n)
//刷新写入任何缓冲的数据基础io.writer
//File 用Sync()
//Writer用Flush()
w.Flush()
}
func writeNoBuf(){
f,err := os.Create(path)
check(err)
defer f.Close()
n,err := f.Write([]byte("write...\n"))
check(err)
fmt.Printf("write %d bytes\n",n)
n2,err := f.WriteString(content)
check(err)
fmt.Printf("write %d bytes\n",n2)
//同步将文件的当前内容提交到稳定存储。
//通常,这意味着将文件系统最近写入数据的内存副本刷新到磁盘。
//File 用Sync()
//Writer用Flush()
f.Sync()
}
func writeString(){
var f *os.File
var err error
if checkFileIsExist(path){
f,err = os.OpenFile(path,os.O_APPEND|os.O_WRONLY,0666)
fmt.Println("文件存在")
}else{
f,err = os.Create(path)
fmt.Println("文件不存在")
}
check(err)
n,err := io.WriteString(f,content)
check(err)
fmt.Printf("write %d bytes\n",n)
}
func writeFile(){
bys := []byte("hello world !\n")
err := ioutil.WriteFile(path,bys,0666)
check(err)
}
25.标准输入,行过滤器
import "bufio"
import "fmt"
import "os"
import "strings"
func main(){
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan(){
ucl := strings.ToUpper(scanner.Text())
fmt.Println(ucl)
if ucl == "BREAK"{
break
}
}
if err := scanner.Err();err != nil{
fmt.Println(os.Stderr,"error:",err)
os.Exit(1)
}
}
26.命令行参数
import "os"
import "fmt"
func main(){
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
arg := os.Args[3]
fmt.Println(argsWithProg)
fmt.Println(argsWithoutProg)
fmt.Println(arg)
}
运行结果:
go run command-line-arguments.go a b c d e f g27.命令行标志flag
import "flag"
import "fmt"
func main(){
wordPtr := flag.String("word","foo","a string")
numPtr := flag.Int("num",86,"a int")
boolPtr := flag.Bool("fork",false,"a bool")
var svar string
flag.StringVar(&svar,"svar","bar","a string var")
flag.Parse()
fmt.Println("word:",*wordPtr)
fmt.Println("num:",*numPtr)
fmt.Println("fork:",*boolPtr)
fmt.Println("svar:",svar)
fmt.Println("tail:",flag.Args())
}
运行结果:
$ go build command-line-flags.go(Setenv、Clearenv只会影响程序当前运行环境中的环境变量。并不会对程序外的系统环境变量产生影响。所以当段代码运行结束时,系统的环境变量并不会发生改变。)
import "os"
import "strings"
import "fmt"
func main(){
os.Setenv("ZZZ","abc")
fmt.Println("ZZZ:",os.Getenv("ZZZ"))
fmt.Println("XXX:",os.Getenv("XXX"))
os.Unsetenv("ZZZ")
fmt.Println("ZZZ:",os.Getenv("ZZZ"))
for _,e := range os.Environ(){
fmt.Println(e)
pair := strings.Split(e,"=")
fmt.Println(pair[0])
}
}
运行结果:
ZZZ: abc29.执行过程
import "syscall"
import "os"
import "os/exec"
func main(){
ls()
gorun()
}
func gorun(){
binary,lookErr := exec.LookPath("go")
if lookErr != nil{
panic(lookErr)
}
args := []string{"go","run","sort.go"}
env := os.Environ()
execErr := syscall.Exec(binary,args,env)
if execErr != nil{
panic(execErr)
}
}
func ls(){
binary,lookErr := exec.LookPath("ls")
if lookErr != nil{
panic(lookErr)
}
args := []string{"ls","-a","-l","-h"}
env := os.Environ()
execErr := syscall.Exec(binary,args,env)
if execErr != nil{
panic(execErr)
}
}
运行结果:
1.ls()则Go只会关注你传入的Signal类型,其他Signal将会按照默认方式处理,大多都是进程退出。因此你需要在Notify中传入你要关注和处理的Signal类型,也就是拦截它们,提供自定义处理函数来改变它们的行为。)
import "fmt"
import "os"
import "os/signal"
import "syscall"
func main(){
signalfun()
}
func signalfun(){
sigs := make(chan os.Signal,1)
done := make(chan bool,1)
signal.Notify(sigs,syscall.SIGINT,syscall.SIGTERM)
go func(){
sig := <-sigs
fmt.Println()
fmt.Println("sig:",sig)
done <- true
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
运行结果:
awaiting signal31.退出程序
import "fmt"
import "os"
func main(){
defer fmt.Println("exit !!!")
os.Exit(1)
}
运行结果:
exit status 1
学习网站:点击打开链接