golang 代码片段


原文链接: golang 代码片段

查找重复行

func findDup() {
    scanner:=bufio.NewScanner(os.Stdin)
    for scanner.Scan(){
        maps[scanner.Text()]++
    }
    for line, count := range maps{
        if count >0 {
            fmt.Printf("line: %s, count: %d\n",
                line, count)
        }
    }
}

心跳包的简单实现

func worker(start chan bool) {
        heartbeat := time.Tick(30 * time.Second)
        for {
                select {
                     // … do some stuff
                case <- heartbeat:
                    //… do heartbeat stuff
                }
        }
}

定时器

duration := 2 * time.Second
timer := time.NewTimer(duration)
go func() {
    for {
        select {
        case <-timer.C:
            fmt.Println("here")
            timer.Reset(duration)
        }
    }
}()

常量生成器

const (
    _ = 1 << (10 * iota)
    KiB // 1024
    MiB // 1048576
    GiB // 1073741824
    TiB // 1099511627776             (exceeds 1 << 32)
    PiB // 1125899906842624
    EiB // 1152921504606846976
    ZiB // 1180591620717411303424    (exceeds 1 << 64)
    YiB // 1208925819614629174706176
)

用chan实现斐波那契数列

import "fmt"
func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}
func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()
	fibonacci(c, quit)
}

字符串的简单映射

func main() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'hello gopher..."))
}

利用chan做延时(超时)

import "time"
import "fmt"
func main() {
    c1 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c1 <- "result 1"
    }()
    select {
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout 1")
    }
}

利用闭包输出递增整数的平方

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}
func main() {
    f := squares()
    fmt.Println(f()) // "1"
    fmt.Println(f()) // "4"
    fmt.Println(f()) // "9"
    fmt.Println(f()) // "16"
}

统计整数包含多少个值为1的2进制数

package main

// pc[i] is the population count of i.
var pc [256]byte

func init() {
	for i := range pc {
		pc[i] = pc[i/2] + byte(i&1)
	}

}

// PopCount returns the population count (number of set bits) of x.
func PopCount(x uint64) int {
	return int(pc[byte(x>>(0*8))] +
		pc[byte(x>>(1*8))] +
		pc[byte(x>>(2*8))] +
		pc[byte(x>>(3*8))] +
		pc[byte(x>>(4*8))] +
		pc[byte(x>>(5*8))] +
		pc[byte(x>>(6*8))] +
		pc[byte(x>>(7*8))])
}

func main() {
	println(PopCount(9))
}

二叉树和利用二叉树排序

package main

import "fmt"

type tree struct {
	value       int
	left, right *tree
}

func Sort(values []int) {
	var root *tree
	for _, v := range values {
		root = add(root, v)
	}
	appendValues(values[:0], root)
}

func appendValues(values []int, t *tree) []int {
	if t != nil {
		values = appendValues(values, t.left)
		values = append(values, t.value)
		values = appendValues(values, t.right)
	}
	return values
}

func add(t *tree, value int) *tree {
	if t == nil {
		t = new(tree)
		t.value = value
		return t
	}
	if value < t.value {
		t.left = add(t.left, value)
	} else {
		t.right = add(t.right, value)
	}
	return t
}

func main() {
	data := []int{1, 5, 6, 3, 2, 7, 8, 9}
	Sort(data)
	fmt.Println(data)
}

通过方法表达式来操作选用哪个方法

type Point struct{ X, Y float64 }

func (p Point) Add(q Point) Point { return Point{p.X + q.X, p.Y + q.Y} }
func (p Point) Sub(q Point) Point { return Point{p.X - q.X, p.Y - q.Y} }

type Path []Point

func (path Path) TranslateBy(offset Point, add bool) {
    var op func(p, q Point) Point
    if add {
        op = Point.Add
    } else {
        op = Point.Sub
    }
    for i := range path {
        // Call either path[i].Add(offset) or path[i].Sub(offset).
        path[i] = op(path[i], offset)
    }
}

interface的类型断言

func sqlQuote(x interface{}) string {
    switch x := x.(type) {
    case nil:
        return "NULL"
    case int, uint:
        return fmt.Sprintf("%d", x) // x has type interface{} here.
    case bool:
        if x {
            return "TRUE"
        }
        return "FALSE"
    case string:
        return sqlQuoteString(x) // (not shown)
    default:
        panic(fmt.Sprintf("unexpected type %T: %v", x, x))
    }
}
ch这个channel的buffer大小是1,所以会交替的为空或为满,所以只有一个case可以进行下去,无论i是奇数或者偶数,它都会打印0 2 4 6 8。
ch := make(chan int, 1)
for i := 0; i < 10; i++ {
    select {
    case x := <-ch:
        fmt.Println(x) // "0" "2" "4" "6" "8"
    case ch <- i:
    }
}

用const 表示字符格式

const template = Warning: you are using %d bytes of storage,%d%% of your quota.

反射

func main() {
  hl := hello
  fv := reflect.ValueOf(hl)
  fmt.Println("fv is reflect.Func ?",fv.Kind() == reflect.Func)
  fv.Call(nil)
}

变长输入参数

func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {

engine.RouterGroup.Use(middleware...)
engine.rebuild404Handlers()
engine.rebuild405Handlers()
return engine

}

删除某个slice的某个元素

for i := range s {

if equal(s[i], element) {
    s = append(s[:i], s[i+1:]...)
}

}

把数组转slice

func main() { 
    a := [3]int{1, 2, 3} 
    b := a[:] 
    fmt.Println(b) 
} 
func main(){
    a := [3]int{1, 2, 3}
    b := (&a)[:]
}

chan数据转发

func forward(src net.Conn, network, address string, timeout time.Duration) {
	defer src.Close()
	dst, err := net.DialTimeout(network, address, timeout)
	if err != nil {
		log.Printf("dial err: %s", err)
		return
	}
	defer dst.Close()

	cpErr := make(chan error)

	go cp(cpErr, src, dst)
	go cp(cpErr, dst, src)

	select {
	case err = <-cpErr:
		if err != nil {
			log.Printf("copy err: %v", err)
		}
	}

	log.Printf("disconnect: %s", src.RemoteAddr())
}

func cp(c chan error, w io.Writer, r io.Reader) {
	_, err := io.Copy(w, r)
	c <- err
	fmt.Println("cp end")
}

保存当前程序的pid

func savePid() {
	pidFilename := ROOT + "/pid/" +filepath.Base(os.Args[0]) + ".pid"
	pid := os.Getpid()
	ioutil.WriteFile(pidFilename, []byte(strconv.Itoa(pid)), 0755)
}

利用struct{}当channel

ch:=make(chan struct{})
ch <- struct{}{}
<-ch

break加label

OuterLoop:
	for i = 0; i < n; i++ {
		for j = 0; j < m; j++ {
			switch a[i][j] {
			case nil:
				state = Error
				break OuterLoop
			case item:
				state = Found
				break OuterLoop
			}
		}
	}

Go语言实现http共享文件服务器

   package main  
    import (  
            "net/http"  
            "os"  
            "strings"  
    )  
    func shareDir(dirName string,port string,ch chan bool){  
            h := http.FileServer(http.Dir(dirName))  
            err := http.ListenAndServe(":"+port,h)  
            if err != nil {  
                    println("ListenAndServe : ",err.Error())  
                    ch <- false  
            }  
    }  
    func main(){  
            ch := make(chanbool)  
            port := "8000"//Default port  
            iflen(os.Args)>1 {  
                    port = strings.Join(os.Args[1:2],"")  
            }  
            go shareDir(".",port,ch)  
            println("Listening on port ",port,"...")  
            bresult := <-ch  
            iffalse == bresult {  
                    println("Listening on port ",port," failed")  
            }  
    }  
简单的TCP代理服务器

package main

import (

"fmt"
"io"
"net"
"os"

)

func main() {

if len(os.Args) != 3 {
    fatal("usage: netfwd localIp:localPort remoteIp:remotePort")
}
localAddr := os.Args[1]
remoteAddr := os.Args[2]
local, err := net.Listen("tcp", localAddr)
if local == nil {
    fatal("cannot listen: %v", err)
}
for {
    conn, err := local.Accept()
    if conn == nil {
        fatal("accept failed: %v", err)
    }
    go forward(conn, remoteAddr)
}

}

func forward(local net.Conn, remoteAddr string) {

remote, err := net.Dial("tcp", remoteAddr)
if remote == nil {
    fmt.Fprintf(os.Stderr, "remote dial failed: %v\n", err)
    return
}
go io.Copy(local, remote)
go io.Copy(remote, local)

}

func fatal(s string, a ...interface{}) {

fmt.Fprintf(os.Stderr, "netfwd: %s\n", fmt.Sprintf(s, a))
os.Exit(2)

}

选择排序是不稳定的。算法复杂度是O(n ^2 )。

package main
import (    
    "fmt"
)

type SortInterface interface {
    sort()
}
type Sortor struct {
    name string
}

func main() {
    arry := []int{6, 1, 3, 5, 8, 4, 2, 0, 9, 7}
    learnsort := Sortor{name: "选择排序--从小到大--不稳定--n*n---"}
    learnsort.sort(arry)
    fmt.Println(learnsort.name, arry)
}

func (sorter Sortor) sort(arry []int) {
    arrylength := len(arry)    for i := 0; i < arrylength; i++ {
        min := i        for j := i + 1; j < arrylength; j++ {            if arry[j] < arry[min] {
                min = j
            }
        }
        t := arry[i]
        arry[i] = arry[min]
        arry[min] = t

    }
}

http://blog.csdn.net/guoer9973/article/details/51924715

重定向golang的panic信息

package main

import (
    "log"
    "os"
    "syscall"
)

// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
    err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
    if err != nil {
        log.Fatalf("Failed to redirect stderr to file: %v", err)
    }
}

import (
	"code.google.com/p/log4go"
	"os"
	"syscall"
)

var (
	kernel32         = syscall.MustLoadDLL("kernel32.dll")
	procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)

func SetStdHandle(stdhandle int32, handle syscall.Handle) error {
	r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
	if r0 == 0 {
		if e1 != 0 {
			return error(e1)
		}
		return syscall.EINVAL
	}
	return nil
}

var f *os.File

func redirect_err() {
	var err error
	f, err = os.Create(`panic.txt`)
	if err != nil {
		log4go.Error("os.Create failed: %v", err)
	}
	err = SetStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
	if err != nil {
		log4go.Error("SetStdHandle failed: %v", err)
	}
}
    go 执行命令并获取stderr

    var stderr io.ReadCloser
    cmd := exec.Command("ping", 
        "localhost"
    )
    stderr, err = cmd.StderrPipe()
	if err != nil {
		glog.Errorln("stderr pipe error: ", err)
	}
	// start cmd
	err = cmd.Start()
	if err != nil {
		glog.Infoln("start cmd error: ", err)
		return err
	}

	glog.Infoln("start ", cmd.Args)
	if stderr != nil {
		reader := bufio.NewReader(stderr)
		go func() {
			for {
				line, err := reader.ReadString(byte('\n'))
				if err != nil || io.EOF == err {
					glog.Infoln("cmd end")
					stderr.Close()
					break
				}
				glog.Infoln("stderr: ", line)
			}
		}()
	}
	err:=cmd.Wait()
	if err!=nil {
	    return err
	}

判断accept是不是临时错误

for {

conn,err:=ln.Accept()
if err, ok := err.(net.Error); ok && err.Temporary() {
    continue
}

}

`