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
}
}