??xml version="1.0" encoding="utf-8" standalone="yes"?>91精品国产高清久久久久久,精品一区二区三区中文字幕在线,另类av一区二区http://www.aygfsteel.com/oathleo/category/53779.html呆在上vzh-cnSun, 22 Dec 2013 13:54:37 GMTSun, 22 Dec 2013 13:54:37 GMT60golang ?接口http://www.aygfsteel.com/oathleo/archive/2013/12/22/407869.htmloathleooathleoSun, 22 Dec 2013 04:45:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/12/22/407869.htmlhttp://www.aygfsteel.com/oathleo/comments/407869.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/12/22/407869.html#Feedback1http://www.aygfsteel.com/oathleo/comments/commentRss/407869.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/407869.htmlconn, err = ln.Accept()
go handleConnection(conn)看到q里我曾l有个疑问,Z么不?nbsp; handleConnection(&conn) ?

下面q个例子解释q个问题

package main

import (
    "fmt"
)

type Interface interface {
    say() string
}

type Object struct {
}

func (this *Object) say() string {
    return "hello"
}

func do(i Interface) string {
    return i.say()
}

func main() {
    o := Object{}
    fmt.Println(do(&o))
    fmt.Printf("CCCCCCCCCCC:%T", o)
}

函数的参C接口定义Q编译器会自己判断参数是对象q是对象的指?br /> 比如Qsay是指针上的方法,所以do只接?span style="background-color: #eeeeee;">Object的指针做参数Qdo(o)是编译不q的

所以看到库里接口做参数cd定义的时候,可以单认为,q个接口肯定是个对象指针Q虽然也可以用对象,单估计没有哪个类库会用)

例如Q?br /> conn, err = ln.Accept()
go handleConnection(conn)

q里conn是个接口Q不需?nbsp;go handleConnection(&conn)

oathleo 2013-12-22 12:45 发表评论
]]>
golang定时定点dhttp://www.aygfsteel.com/oathleo/archive/2013/12/19/407774.htmloathleooathleoThu, 19 Dec 2013 08:15:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/12/19/407774.htmlhttp://www.aygfsteel.com/oathleo/comments/407774.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/12/19/407774.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/407774.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/407774.htmlpackage main

import (
    "fmt"
    "mag/common"
    "time"
)

func main() {
    c := make(chan bool, 10)

    tt := common.GetTodayGivenTime("161300")
    dd := common.SinceNow(tt)
    time.AfterFunc(dd, func() { //非阻?br />        //后箋?4时建立目录
        ticker24h := time.NewTicker(5 * time.Second)
        for {
            select {
            case <-ticker24h.C:
                fmt.Println("print")
            }
        }
    })

    <-c
}

oathleo 2013-12-19 16:15 发表评论
]]>
golang append时slice len ?caphttp://www.aygfsteel.com/oathleo/archive/2013/11/20/406595.htmloathleooathleoWed, 20 Nov 2013 10:48:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/11/20/406595.htmlhttp://www.aygfsteel.com/oathleo/comments/406595.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/11/20/406595.html#Feedback1http://www.aygfsteel.com/oathleo/comments/commentRss/406595.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/406595.html
声明:
源slice= src
dslice = app
l果slice=tar
append?/div>
len tar === len src +   len app
1Q如果len(src) + len(app) <= cap(src)    cap tar  =   cap(src)
2Q否?nbsp;
      a) len(src) + len(app) > 2* cap(src)     cap tar  =   len(src) + len(app)
      b) cap(src) < len(src) + len(app) <= 2* cap(src)    cap tar = 2* cap(src)
    data := make([]int, 10, 20)
    data[0] = 1
    data[1] = 2

    dataappend := make([]int, 12, 30)//修改q个len 
    dataappend[0] = 1
    dataappend[1] = 2

    result := append(data, dataappend)

    result[0] = 99
    result[11] = 98

    fmt.Println("length:", len(data), "cap:", cap(data), ":", data)
    fmt.Println("result length:", len(result), "cap:", cap(result), ":", result)
    fmt.Println("length:", len(dataappend), "cap:", cap(dataappend), ":", dataappend)


oathleo 2013-11-20 18:48 发表评论
]]>golang slice分割和append copyq是引用http://www.aygfsteel.com/oathleo/archive/2013/11/20/406594.htmloathleooathleoWed, 20 Nov 2013 10:46:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/11/20/406594.htmlhttp://www.aygfsteel.com/oathleo/comments/406594.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/11/20/406594.html#Feedback1http://www.aygfsteel.com/oathleo/comments/commentRss/406594.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/406594.html1.slice1:= slice[0:2]
引用Q非复制Q所以Q何对slice1或slice的修攚w会媄响对?/div>
data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
data1 := data[0:2]
data1[0] = 99
fmt.Println(data1)
fmt.Println(data)
[99 2]
[99 2 3 4 5 6 7 8 9 0]
2.append
append 比较Ҏ
声明:
源slice= src
dslice = app
l果slice=tar
1Q如果len(src) + len(app) <= cap(src)  src和tar 是指向同一数据引用 Q即修改src或tarQ会影响Ҏ
2Q否?tar 是copy的方?nbsp;src + app Q?span style="color: #ff0000; ">即修改src或tarQ不会媄响对?/span>
无论哪种情况不会影响appQ因为app都会用copy的方式进入tar
 
func test2() {
data := make([]int, 10, 20)
data[0] = 1
data[1] = 2
dataappend := make([]int, 10, 20)//len <=10 ?nbsp; result[0] = 99 ?影响源Slice
dataappend[0] = 1
dataappend[1] = 2
result := append(data, dataappend...)
result[0] = 99
result[11] = 98
fmt.Println("length:", len(data), ":", data)
fmt.Println("length:", len(result), ":", result)
fmt.Println("length:", len(dataappend), ":", dataappend)
}


oathleo 2013-11-20 18:46 发表评论
]]>golang ? L定长数组里的0 []byte ?stringhttp://www.aygfsteel.com/oathleo/archive/2013/11/19/406513.htmloathleooathleoTue, 19 Nov 2013 02:16:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/11/19/406513.htmlhttp://www.aygfsteel.com/oathleo/comments/406513.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/11/19/406513.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/406513.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/406513.html index := bytes.IndexByte(buf_PN, 0)
rbyf_pn := buf_PN[0:index]


oathleo 2013-11-19 10:16 发表评论
]]>
golang?windows下杀q程http://www.aygfsteel.com/oathleo/archive/2013/11/15/406377.htmloathleooathleoFri, 15 Nov 2013 06:07:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/11/15/406377.htmlhttp://www.aygfsteel.com/oathleo/comments/406377.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/11/15/406377.html#Feedback3http://www.aygfsteel.com/oathleo/comments/commentRss/406377.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/406377.html c := exec.Command("taskkill.exe", "/f", "/im", "test.exe")
err := c.Start()


oathleo 2013-11-15 14:07 发表评论
]]>
golang slice Append http://www.aygfsteel.com/oathleo/archive/2013/11/05/406016.htmloathleooathleoTue, 05 Nov 2013 08:39:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/11/05/406016.htmlhttp://www.aygfsteel.com/oathleo/comments/406016.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/11/05/406016.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/406016.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/406016.html
切片s1上记录的切片信息复制ls2Q?br />
1.如果s1指向的底层array长度不够Qappend的过E会发生如下操作Q内存中不仅新开辟一块区域存储append后的切片信息Q而且需要新开辟一块区域存储底层arrayQ复制原来的array臌块新array中)Q最后再append新数据进新array中,q样Qs2指向新array?br />
2.如果s1指向的底层array长度?
s2和s1指向同一个arrayQappend的结果是内存中新开辟一个区域存储新切片信息?br />
开辟一块区域存储底层array 使用下面的策略:
1.如果 增加?len < s的cap ?新s的cap*2
2.如果 增加?len > s的cap ?新s的cap = 老cap + 增加数据?len

oathleo 2013-11-05 16:39 发表评论
]]>
golang 定时http://www.aygfsteel.com/oathleo/archive/2013/10/10/404842.htmloathleooathleoThu, 10 Oct 2013 07:07:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/10/10/404842.htmlhttp://www.aygfsteel.com/oathleo/comments/404842.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/10/10/404842.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404842.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404842.html

 // (A)
time.AfterFunc(5 * time.Minute, func() {
    fmt.Printf("expired")
}

// (B) create a Timer object
timer := time.NewTimer(5 * time.Minute)
<-timer.C
fmt.Printf("expired")

// (C) time.After() returns timer.C internally
<-time.After(5 * time.Minute)
fmt.Printf("expired")


oathleo 2013-10-10 15:07 发表评论
]]>
golang 非缓冲通道 recv 的操?肯定 ?send 操作 之前发生http://www.aygfsteel.com/oathleo/archive/2013/10/10/404830.htmloathleooathleoThu, 10 Oct 2013 02:56:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/10/10/404830.htmlhttp://www.aygfsteel.com/oathleo/comments/404830.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/10/10/404830.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404830.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404830.html 一定会? “向通道发送数?#8221;的操作完成前发生?br />
package main

import (
    "fmt"
)

var c = make(chan int)
var str string

func ready() {
    str = "abc"
    fmt.Println("ready1")
    <-c //get
    fmt.Println("ready2")
}

func main() {
    go ready()
    c <- 1 //put
    fmt.Println(str)
}

ready1
ready2
abc


oathleo 2013-10-10 10:56 发表评论
]]>
Go指针 new makehttp://www.aygfsteel.com/oathleo/archive/2013/10/08/404721.htmloathleooathleoTue, 08 Oct 2013 02:49:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/10/08/404721.htmlhttp://www.aygfsteel.com/oathleo/comments/404721.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/10/08/404721.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404721.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404721.htmlnew(T) 分配了零值填充的T
cd的内存空?q且q回其地址,一?T cd的倹{用Go 的术语说,它返回了一?/div>
指针,指向新分配的cdT 的零倹{有一炚w帔R?
new q回指针?br />
内徏函数make(T, args) 与new(T) 有着不同的功能。它只能创徏slice,map
和channel,q且q回一个有初始?非零)的T cd,而不?T?/span>本质来讲,Dq?/div>
三个cd有所不同的原因是指向数据l构的引用在使用前必被初始化?br />
T{name:"aaa",age:11}
q回 Tcd 而不?T


oathleo 2013-10-08 10:49 发表评论
]]>go原生数据效率http://www.aygfsteel.com/oathleo/archive/2013/09/29/404597.htmloathleooathleoSun, 29 Sep 2013 01:57:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/29/404597.htmlhttp://www.aygfsteel.com/oathleo/comments/404597.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/29/404597.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404597.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404597.html
先上代码
package main

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

type RTValue struct {
    Time   int32
    Status int16
    Value  float32
}

func main() {

    size := 1000000
    col := make([]RTValue, size)
    for i := 0; i < size; i++ {
        col[i] = RTValue{Time: int32(i), Status: int16(i), Value: rand.Float32()}
    }

    fmt.Println("send data:", col[size-1])
    var opbuff *opbuf.OPBuffer = opbuf.NewOPBuffer()
    start := time.Now().UnixNano()
    for i := 0; i < size; i++ {
        //        opbuff.PutByte(col[i].Data)
        opbuff.PutInt32(col[i].Time)
        opbuff.PutInt16(col[i].Status)
        opbuff.PutFloat32(col[i].Value)
    }
    fmt.Println("send cost:", (time.Now().UnixNano()-start)/1000000)

    opbuff.Flush()

    start = time.Now().UnixNano()
    for i := 0; i < size; i++ {
        col[i].Time,_ = opbuff.GetInt32()
        col[i].Status,_ = opbuff.GetInt16()
        col[i].Value,_ = opbuff.GetFloat32()
    }
    fmt.Println("rev cost:", (time.Now().UnixNano()-start)/1000000)
    fmt.Println("rev data:", col[size-1])

}
123

Go原生代码性能Q?/div>
total record: 1000000
send data: {999999 16959 0.69153386}
send cost: 93
rev cost: 61
rev data: {999999 16959 0.69153386}
 
l论Q?/div>
1.不管什么语aQ?span style="color: #ff0000">大批量同cd数据的传?/span>Q原生性能q是比第三方序列? 效率高很?
2.C++ 使用memcpy put 原始cdQ效率还是比go高很?br />
C++原生代码性能Q?/div>
total record 1000000
time pack 11 ms
time unpack 57 ms
 
 


oathleo 2013-09-29 09:57 发表评论
]]>go对象序列化和反序列化http://www.aygfsteel.com/oathleo/archive/2013/09/29/go_ser.htmloathleooathleoSun, 29 Sep 2013 01:52:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/29/go_ser.htmlhttp://www.aygfsteel.com/oathleo/comments/404595.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/29/go_ser.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404595.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404595.htmlq程
1.对象序列化ؓ byte
2.byte反序为对?br />3.gzip压羃byte

试语言go
试ҎQ? raw byteQjson ,bson, msgpack Qprotostuff需要先做对象配|文Ӟ比较ȝQ通常认ؓ和msgpack性能相当 Q?br />l果Qmsgpack 胜出


大小
gzip压羃后大?br /> 对象到byte耗时
byte到对象耗时
raw 10000000
6573252Q?5%Q?/td> 未测?br /> 未测?/td>
json
47515988 7919511 (17%) 3248ms 5280ms
bson
49888910 9506965 Q?9%Q?br /> 3863ms 6235ms
msgpack
29934223 7448484 2046ms 3113ms


raw data: 1000000
raw data gzip compress: 6573252 //gzip压羃后大?br />
start: 1000000
Marshal cost: 3248  //json 序列化耗时
json string: 47515988 
json byte: 47515988  //二进制数l大?br />Unmarshal cost: 5280  //json 反序列化耗时
test data: {1 100 0.9405091}
json gzip compress: 7919511 //gzip压羃后大?br />
start
Marshal cost: 3863
bson byte: 49888910
Unmarshal cost: 6235
test data: {1 100 0.9405091}
bson gzip compress: 9506965


start: 1000000
Marshal cost: 2046
msgpack: 29934223
Unmarshal cost: 3113
test data: {1 100 0.9405091}
msgpack gzip compress: 7448484

oathleo 2013-09-29 09:52 发表评论
]]>
bson和jsonhttp://www.aygfsteel.com/oathleo/archive/2013/09/23/Bson_Json.htmloathleooathleoMon, 23 Sep 2013 06:08:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/23/Bson_Json.htmlhttp://www.aygfsteel.com/oathleo/comments/404326.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/23/Bson_Json.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404326.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404326.html
l果bson比jsonq大一点,实Z意料

个hl论是BSONҎjson更加适合存储Q在传输上没有太大优?br />
  BSON相对JSon
1.更快的遍历速度
2.操作更简?/div>
3.增加了额外的数据cd

raw data: 10000
raw data gzip compress: 6553

json string: 44524
json byte: 44524
json gzip compress: 8125

bson byte: 46910
bson gzip compress: 9721


package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
    "labix.org/v2/mgo/bson"
    "math/rand"
)

type HisCollection struct {
    RTValues []RTValue
}

type RTValue struct {
    Time   int32
    Status int16
    Value  float32
}

func main() {
    fmt.Println("start")

    size := 1000
    col := make([]RTValue, size)

    for i := 0; i < size; i++ {
        col[i] = RTValue{Time: int32(i), Status: 100, Value: rand.Float32()}
    }

    his := HisCollection{RTValues: col}
    data, err := bson.Marshal(&his)
    if err != nil {
        panic(err)
    }
    //    fmt.Println(data)
    fmt.Println("bson byte:", len(data))

    var compress_data_buf bytes.Buffer
    writer := gzip.NewWriter(&compress_data_buf)
    defer writer.Close()

    writer.Write(data)
    writer.Flush()

    fmt.Println("bson gzip compress:",len(compress_data_buf.Bytes()))

}

package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
    "math/rand"
    "openplant/opnet"
)

func main() {
    var compress_data_buf bytes.Buffer
    writer := gzip.NewWriter(&compress_data_buf)
    defer writer.Close()

    size := 1000
    for i := 0; i < size; i++ {
        writer.Write(opnet.WarpInt32ToByte(int32(i)))
        writer.Write(opnet.WarpInt16ToByte(int16(100)))
        writer.Write(opnet.WarpFloat32ToByte(rand.Float32()))
    }

    writer.Flush()

    fmt.Println("raw data:", 10000)

    fmt.Println("raw data gzip compress:", len(compress_data_buf.Bytes()))

}
111

package main

import (
    "bytes"
    "compress/gzip"
    "encoding/json"
    "fmt"
    "math/rand"
)

type HisCollection struct {
    RTValues []RTValue
}

type RTValue struct {
    Time   int32
    Status int16
    Value  float32
}

func main() {
    fmt.Println("start")

    size := 1000
    col := make([]RTValue, size)

    for i := 0; i < size; i++ {
        col[i] = RTValue{Time: int32(i), Status: 100, Value: rand.Float32()}
    }

    his := HisCollection{RTValues: col}

    data, err := json.Marshal(&his)

    fmt.Println("json string:", string(data))
    fmt.Println("json string:", len(string(data)))

    if err != nil {
        panic(err)
    }
    //    fmt.Println(data)
    fmt.Println("json byte:", len(data))

    var compress_data_buf bytes.Buffer
    writer := gzip.NewWriter(&compress_data_buf)
    defer writer.Close()

    writer.Write(data)
    writer.Flush()

    fmt.Println("json gzip compress:", len(compress_data_buf.Bytes()))

}


oathleo 2013-09-23 14:08 发表评论
]]>golang ? bson ?struct 转换http://www.aygfsteel.com/oathleo/archive/2013/09/22/golang_bson_struct_mongo.htmloathleooathleoSun, 22 Sep 2013 08:08:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/22/golang_bson_struct_mongo.htmlhttp://www.aygfsteel.com/oathleo/comments/404287.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/22/golang_bson_struct_mongo.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404287.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404287.htmlbson的介l不说了
golang下的解析包找??一个是mongo?a >http://labix.org/gobson
Q另外一个比较小?a >https://github.com/sbunce/bson

q里用的是mongo的作Z子?br />对象加上不同的注解,
可以L转成xml json bson x都兴?nbsp;
package main

import (
    "fmt"
    "labix.org/v2/mgo/bson"
)

type TestStruct struct {
    Name string
    ID   int32
}

func main() {
    fmt.Println("start")
    data, err := bson.Marshal(&TestStruct{Name: "Bob"})
    if err != nil {
        panic(err)
    }
    fmt.Println("%q", data)

    value := TestStruct{}
    err2 := bson.Unmarshal(data, &value)
    if err2 != nil {
        panic(err)
    }
    fmt.Println("value:", value)

    mmap := bson.M{}
    err3 := bson.Unmarshal(data, mmap)
    if err3 != nil {
        panic(err)
    }
    fmt.Println("mmap:", mmap)

}


oathleo 2013-09-22 16:08 发表评论
]]>
Golang 异常处理http://www.aygfsteel.com/oathleo/archive/2013/09/22/404272.htmloathleooathleoSun, 22 Sep 2013 01:32:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/22/404272.htmlhttp://www.aygfsteel.com/oathleo/comments/404272.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/22/404272.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/404272.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/404272.htmlPanic和Recover

Go没有像Java那样的异常机Ӟ它不能抛出异常,而是使用?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">recover机制。一定要CQ你应当把它作ؓ最后的手段来用,也就是说Q你的代码中应当没有Q或者很有panic的东ѝ这是个强大的工Ph智地使用它。那么,我们应该如何使用它呢Q?/p>

Panic

是一个内建函敎ͼ可以中断原有的控制流E,q入一个o人恐慌的程中。当函数F调用panicQ函?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">F的执行被中断Q但?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">F中的延迟函数会正常执行,然后Fq回到调用它的地斏V在调用的地方,F的行为就像调用了panic。这一q程l箋向上Q直到发?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">goroutine中所有调用的函数q回Q此时程序退出。恐慌可以直接调?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic产生。也可以p行时错误产生Q例如访问越界的数组?/p>

Recover

是一个内建的函数Q可以让q入令h恐慌的流E中?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">goroutine恢复q来?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">recover仅在延迟函数中有效。在正常的执行过E中Q调?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">recover会返?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">nilQƈ且没有其它Q何效果。如果当前的goroutine陷入恐慌Q调?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">recover可以捕获?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic的输入|q且恢复正常的执行?/p>

下面q个函数演示了如何在q程中?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic

var user = os.Getenv("USER")  func init() {     if user == "" {         panic("no value for $USER")     } } 

下面q个函数查作为其参数的函数在执行时是否会产生panicQ?/strong>

func throwsPanic(f func()) (b bool) {     defer func() {         if x := recover(); x != nil {             b = true         }     }()     f() //执行函数fQ如果f中出CpanicQ那么就可以恢复回来     return } 

最Ҏ理解是l个例子Q文章里有例子:

package main  import(     "fmt"     //"os" )  var user = "" func inita() {     defer func(){         fmt.Print("defer##\n")     }()     if user == "" {         fmt.Print("@@@before panic\n")         panic("no value for user\n")         fmt.Print("!!after panic\n")     } }  func throwsPanic (f func()) (b bool){     defer func(){         if x:= recover(); x != nil{             fmt.Print(x)             b = true         }     }()     f()     fmt.Print("after the func run")     return }  func main(){     throwsPanic(inita) } 

执行l果Q?/p>

D:\go>go run b.go
@@@before panic
defer##
no value for user

如上面所说的Q?/p>

panic?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">user=""Ӟ打断了函数的执行Q?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">fmt.Print("!!after panic\n")没有执行?但函C的gq函C正常执行Q打C defer##。然后返回到调用该函数的地方Ql上面的q程?/p>

直到执行完所有函数的deferQ退出程序?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">Recover可以捕获?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">panic的|上面的打?code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: consolas, courier; font-size: 13px; line-height: 20px;">no value for user。ƈ且恢复正常的执行?/p>

oathleo 2013-09-22 09:32 发表评论
]]>
Go语言的传参和传引?/title><link>http://www.aygfsteel.com/oathleo/archive/2013/09/16/404106.html</link><dc:creator>oathleo</dc:creator><author>oathleo</author><pubDate>Mon, 16 Sep 2013 01:23:00 GMT</pubDate><guid>http://www.aygfsteel.com/oathleo/archive/2013/09/16/404106.html</guid><wfw:comment>http://www.aygfsteel.com/oathleo/comments/404106.html</wfw:comment><comments>http://www.aygfsteel.com/oathleo/archive/2013/09/16/404106.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oathleo/comments/commentRss/404106.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oathleo/services/trackbacks/404106.html</trackback:ping><description><![CDATA[<div style="padding-top: 5px; padding-bottom: 5px; margin: 0px 0px 10px; font-family: 微Y雅黑, Verdana, sans-serif, 宋体; font-size: 13px; line-height: normal; background-color: #ffffff;"><h1>Go语言的传参和传引用[OSC源创会主题补?]</h1><div style="margin: 0px; color: #666666;"><span style="padding: 0px; margin: 0px; float: right;"><span id="p_attention_count" style="padding: 0px; margin: 0px 2px; font-weight: bold; color: #aa0000;">66</span>人收藏此文章, <span id="attention_it" style="padding: 0px; margin: 0px;"><a id="favor_trigger" title="d到收藏夹" style="padding: 0px; margin: 0px; color: #aa0000; outline: 0px;">我要收藏</a></span></span>发表?天前(2013-09-14 22:10) , 已有<strong style="padding: 0px; margin: 0px 2px; color: #aa0000;">1496</strong>ơ阅?Q共<strong style="padding: 0px; margin: 0px 2px; color: #aa0000;"><a style="padding: 0px; margin: 0px; color: #aa0000; outline: 0px;">12</a></strong>个评?/div></div><div style="padding: 20px; margin: 0px; background-color: #f6f6f6; line-height: 23px; font-family: 微Y雅黑, Verdana, sans-serif, 宋体; font-size: 13px;"><p style="padding: 0px; margin: 0px; font-size: 18px; color: #15a230;">目录Q[ <span style="padding: 0px; margin: 0px; font-size: 14px;"><a id="AnchorContentToggle" title="收v" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">-</a></span> ]</p><div class="wmqeeuq" id="AnchorContent" style="padding: 10px; margin: 0px;"><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">传参和传引用的问?/a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">slice不是引用!</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">什么叫引用?</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">Z么slice不是引用?</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">Z么很多h误以为slice是引用呢?</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">传指针和传引用是{h的吗?</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">所有类型的函数参数都是传值的!</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">那Go语言有传引用的说法吗?</a></li><li style="padding: 3px 0px; margin: 0px; list-style: none; text-indent: 20px;"><a style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px; text-decoration: none;">ȝ</a></li></div></div><div style="margin: 0px; font-size: 10.5pt; overflow: hidden; color: #333333; line-height: 25px; font-family: 微Y雅黑, Verdana, sans-serif, 宋体; background-color: #ffffff;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">OSC源创会主题补充系?</p><ol style="padding: 0px; margin: 10px 20px; list-style-position: inside;"><li style="padding: 0px; margin: 0px;"><a rel="nofollow" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px;">Go语言的传参和传引?/a></li><li style="padding: 0px; margin: 0px;"><a rel="nofollow" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px;">Go语言的类型{换和cd断言</a></li></ol><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">Go语言规范虽然很简? 但是深入掌握Go语言却需要很多底层知?</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">本来<a rel="nofollow" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px;">W?0期的武汉OSC源创?/a>有Go语言的专题讲? 谁知道说取消取消了.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">我最q也整理了一些Go语言资料, 有Go语言的历?现状/未来发展的八卦和Go语言常见的问题和陷阱两个部分, 本来打算OSC源创会能和武汉的Gopher分n 下的, 谁知?׃不是赞助商也不是微Y的大?dҎ本不lQ何的Z.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">100+人数的交会基本都是扯E, q是规模的讨论沙龙比较靠谱, 以后再也不会去OSC源创会当听众?</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">现在计划各个小问题暂时作ؓ博客发表.</p><h2>传参和传引用的问?/h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">很多非官方的文档和教?包括一些已l出版的图书), 对Go语言的传参和引用的讲?都有很多问题. D众多Go语言新手对Go的函数参C参有很多误解.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">而传参和传引用是~程语言的根本问? 如果q个问题理解错误可能会导致很多问?</p><h2>slice不是引用!</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">首先, Go语言的函数调用参数全部是传值的, 包括 <code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">slice</code>/<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">map</code>/<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">chan</code> 在内所有类? 没有传引用的说法.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">具体LGo语言的规?</p><blockquote style="padding: 20px 60px; margin: 15px 0px; quotes: '', ''; position: relative; background-color: #f6f6f6;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">After they are evaluated, <strong style="padding: 0px; margin: 0px;">the parameters of the call are passed by value</strong> to the function and the called function begins execution.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">from: <a rel="nofollow" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px;">http://golang.org/ref/spec#Calls</a></p></blockquote><h2>什么叫引用?</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">比如有以下代?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">var a Object doSomething(a) // 修改a的?print(a) </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">如果函数<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">doSomething</code>修改<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>的? 然后<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">print</code>打印出来的也是修改后的? 那么可以认?code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">doSomething</code>是通过引用的方式用了参数<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>.</p><h2>Z么slice不是引用?</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">我们构造以下的代码:</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">func main() { a := []int{1,2,3} fmt.Println(a) modifySlice(a) fmt.Println(a) } func modifySlice(data []int) { data = nil } </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">其中<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">modifySlice</code>修改了切?code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>, 输出l果如下:</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">[1 2 3] [1 2 3] </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">说明<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>在调?code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">modifySlice</code>前后q没有Q何变? 因此<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>必然是传值的!</p><h2>Z么很多h误以为slice是引用呢?</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">可能?因ؓ很多新接触Go语言的新? 看到Go语言的文说Go的切片和C语言的数l类? 而C语言的数l是传地址?注意: 不是传引?).</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">下面q个代码可能是错误的Ҏ:</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">func main() { a := []int{1,2,3} fmt.Println(a) modifySliceData(a) fmt.Println(a) } func modifySliceData(data []int) { data[0] = 0 } </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">输出?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">[1 2 3] [0 2 3] </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">函数<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">modifySliceData</code>实通过参数修改了切片的内容.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">但是h? 修改通过函数修改参数内容的机制有很多, 其中传参数的地址可以修改参数的?其实是修改参C指针指向的数?, q不是只有引用一U方?</p><h2>传指针和传引用是{h的吗?</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">比如有以下代?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">func main() { a := new(int) fmt.Println(a) modify(a) fmt.Println(a) } func modify(a *int) { a = nil } </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">输出?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">0xc010000000 0xc010000000 </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">可以看出指针<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>本nq没有变? 传指针或传地址也只能修Ҏ针指向的内存的? q不能改变指针本w在?</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;"><strong style="padding: 0px; margin: 0px;">因此, 函数参数传传指针也是传值的, q不是传引用!</strong></p><h2>所有类型的函数参数都是传值的!</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">包括<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">slice</code>/<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">map</code>/<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">chan</code>{基cd和自定义的类型都是传值的.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">但是因ؓ<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">slice</code>?code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">map</code>/<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">chan</code>底层l构的差? 又导致了它们传值的影响q不完全{同.</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">重点归纳如下:</p><ul style="padding: 0px; margin: 10px 20px; list-style-position: inside;"><li style="padding: 0px; margin: 0px;">GoSpec: the parameters of the call are passed by value!</li><li style="padding: 0px; margin: 0px;">map/slice/chan 都是传? 不是传引?/li><li style="padding: 0px; margin: 0px;">map/chan 对应指针, 和引用类?/li><li style="padding: 0px; margin: 0px;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">slice 是结构体和指针的混合?/p></li><li style="padding: 0px; margin: 0px;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">slice ?values/count/capacity {信? 是按g?/p></li><li style="padding: 0px; margin: 0px;">slice 中的 values 是指? 按g?/li><li style="padding: 0px; margin: 0px;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">按g递的 slice 只能修改values指向的数? 其他都不能修?/p></li><li style="padding: 0px; margin: 0px;"><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">以指针或l构体的角度? 都是g?</p></li></ul><h2>那Go语言有传引用的说法吗?</h2><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">Go语言其实也是有传引用的地方的, 但是不是函数的参? 而是闭包对外部环境是通过引用讉K?</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">查看以下的代?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">func main() { a := new(int) fmt.Println(a) func() { a = nil }() fmt.Println(a) } </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">输出?</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">0xc010000000 <nil> </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">因ؓ闭包是通过引用的方式用外部环境的<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>变量, 因此可以直接修改<code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">a</code>的?</p><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">比如下面2D代码的输出是截然不同的, 原因是W二个代码是通过闭包引用的方式输?code style="padding: 2px 5px; margin: 0px 2px; border: 1px solid #dddddd; background-color: #f6f6f6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">i</code>变量:</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) // Output: 4 3 2 1 0 } fmt.Printf("\n") for i := 0; i < 5; i++ { defer func(){ fmt.Printf("%d ", i) } () // Output: 5 5 5 5 5 } </code></pre><p style="padding: 0px; margin: 12px 0px; letter-spacing: 1px;">像第二个代码是于闭包引用导致的副作? 回避q个副作用的办法是通过参数传值或每次闭包构造不同的临时变量:</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: break-all;">// Ҏ1: 每次循环构造一个时变?i for i := 0; i < 5; i++ { i := i defer func(){ fmt.Printf("%d ", i) } () // Output: 4 3 2 1 0 } // Ҏ2: 通过函数参数传惨 for i := 0; i < 5; i++ { defer func(i int){ fmt.Printf("%d ", i) } (i) // Output: 4 3 2 1 0 } </code></pre><h2>ȝ</h2><ul style="padding: 0px; margin: 10px 20px; list-style-position: inside;"><li style="padding: 0px; margin: 0px;">函数参数传? 闭包传引?</li><li style="padding: 0px; margin: 0px;">slice ?values/count/capacity {信? 是按g?/li><li style="padding: 0px; margin: 0px;">按g递的 slice 只能修改values指向的数? 其他都不能修?/li><li style="padding: 0px; margin: 0px;">slice 是结构体和指针的混合?/li></ul></div><img src ="http://www.aygfsteel.com/oathleo/aggbug/404106.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oathleo/" target="_blank">oathleo</a> 2013-09-16 09:23 <a href="http://www.aygfsteel.com/oathleo/archive/2013/09/16/404106.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组和切?/title><link>http://www.aygfsteel.com/oathleo/archive/2013/09/12/403973.html</link><dc:creator>oathleo</dc:creator><author>oathleo</author><pubDate>Thu, 12 Sep 2013 01:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/oathleo/archive/2013/09/12/403973.html</guid><wfw:comment>http://www.aygfsteel.com/oathleo/comments/403973.html</wfw:comment><comments>http://www.aygfsteel.com/oathleo/archive/2013/09/12/403973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oathleo/comments/commentRss/403973.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oathleo/services/trackbacks/403973.html</trackback:ping><description><![CDATA[<div class="wmqeeuq" id="cnblogs_post_body" style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal; background-color: #eeeedd; word-break: normal !important;"><div class="wmqeeuq" id="markdown-preview" style="line-height: 1.6; overflow: hidden;"><h3>数组 Arrays</h3><p style="margin: 0px 0px 15px; line-height: 21px;">数组是内|?build-in)cd,是一l同cd数据的集合,它是值类型,通过?开始的下标索引讉K元素倹{在初始化后长度是固定的Q无法修改其长度。当作ؓҎ的入参传入时复制一份数l而不是引用同一指针。数l的长度也是其类型的一部分Q通过内置函数len(array)获取光度?/p><h4>初始?/h4><p style="margin: 0px 0px 15px; line-height: 21px;">数组的初始化有多UŞ?<a style="color: #770000; text-decoration: none;">查看CZ代码</a> , <a style="color: #770000; text-decoration: none;">在线q行CZ代码</a></p><ul style="margin: 15px 0px 15px 45px; padding-left: 10px;"><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">[5] int {1,2,3,4,5}</code> <br />长度?的数l,其元素gơؓQ?Q?Q?Q?Q?</li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">[5] int {1,2}</code> <br />长度?的数l,其元素gơؓQ?Q?Q?Q?Q? 。在初始化时没有指定初值的元素会赋gؓ其元素类型int的默认?,string的默认值是<strong>""</strong></li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">[...] int {1,2,3,4,5}</code> <br />长度?的数l,光度是Ҏ初始化时指定的元素个数决定的</li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">[5] int { 2:1,3:2,4:3}</code> <br />长度?的数l,key:value,其元素gơؓQ?Q?Q?Q?Q?。在初始化时指定?Q?Q?索引中对应的|1Q?Q?</li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">[...] int {2:1,4:3}</code> <br />长度?的数l,起元素gơؓQ?Q?Q?Q?Q?。由于指定了最大烦?对应的?Q根据初始化的元素个数确定其长度?</li></ul><h4><a name="-1" style="color: rgb(119, 0, 0); text-decoration: none; display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0px; left: 0px; bottom: 0px;"></a>赋g使用</h4><p style="margin: 0px 0px 15px; line-height: 21px;">数组通过下标讉K元素Q可修改其元素?/p><pre style="margin: 15px; white-space: pre-wrap; word-wrap: break-word; background-color: #141414; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: #f2f2f2; background-position: initial initial; background-repeat: initial initial;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: pre; font-size: 14px; font-family: monospace, Monaco; background-position: initial initial; background-repeat: initial initial;">arr :=[...] int {1,2,3,4,5} arr[4]=arr[1]+len(arr) //arr[4]=2+5 </code></pre><p style="margin: 15px 0px; line-height: 21px;">通过for遍历数组元素,<a style="color: #770000; text-decoration: none;">查看CZ代码</a>,<a style="color: #770000; text-decoration: none;">在线q行CZ代码</a></p><pre style="margin: 15px; white-space: pre-wrap; word-wrap: break-word; background-color: #141414; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: #f2f2f2; background-position: initial initial; background-repeat: initial initial;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: pre; font-size: 14px; font-family: monospace, Monaco; background-position: initial initial; background-repeat: initial initial;">arr := [5]int{5, 4, 3} for index, value := range arr { fmt.Printf("arr[%d]=%d \n", index, value) } for index := 0; index < len(arr); index++ { fmt.Printf("arr[%d]=%d \n", index, arr[index]) } </code></pre><p style="margin: 15px 0px; line-height: 21px;">数组是值类型,一个数l赋值给另一个数l时复制一份新的元?<a style="color: #770000; text-decoration: none;">查看CZ代码</a>,<a style="color: #770000; text-decoration: none;">在线q行CZ代码</a></p><pre style="margin: 15px; white-space: pre-wrap; word-wrap: break-word; background-color: #141414; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: #f2f2f2; background-position: initial initial; background-repeat: initial initial;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: pre; font-size: 14px; font-family: monospace, Monaco; background-position: initial initial; background-repeat: initial initial;">arr2 := [5]int{1, 2} arr5 := arr2 arr5[0] = 5 arr2[4] = 2 fmt.Printf(" arr5= %d \n arr2=%d \n arr5[0]==arr2[0]= %s \n", arr5, arr2, arr5[0] == arr2[0]) OutPut: arr5=[5 2 0 0 0] arr2=[1 2 0 0 2] arr5[0]==arr2[0]= false </code></pre><h3><a name="-slices" style="color: rgb(119, 0, 0); text-decoration: none; display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0px; left: 0px; bottom: 0px;"></a>切片 Slices</h3><p style="margin: 0px 0px 15px; line-height: 21px;">数组的长度不可改变,在特定场景中q样的集合就不太适用QGo中提供了一U灵z,功能强悍的内|类?strong>Slices</strong>切片,与数l相比切片的长度是不固定的,可以q加元素Q在q加时可能切片的容量增大。切片中有两个概念:一?strong>len长度</strong>Q二?strong>cap定w</strong>Q长度是指已l被赋过值的最大下?1Q可通过内置函数len()获得。容量是指切片目前可容纳的最多元素个敎ͼ可通过内置函数cap()获得。切片是引用cdQ因此在当传递切片时引用同一指针Q修改值将会媄响其他的对象?/p><h4><a name="-2" style="color: rgb(119, 0, 0); text-decoration: none; display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0px; left: 0px; bottom: 0px;"></a>初始?/h4><p style="margin: 0px 0px 15px; line-height: 21px;">切片可以通过数组来初始化Q也可以通过内置函数make()初始?.初始化时len=cap,在追加元素时如果定wcap不时将按len?strong>2</strong>倍扩?nbsp;<a style="color: #770000; text-decoration: none;">查看CZ代码</a>Q?a style="color: #770000; text-decoration: none;">在线q行CZ代码</a></p><ul style="margin: 15px 0px 15px 45px; padding-left: 10px;"><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s :=[] int {1,2,3 }</code> <br />直接初始化切片,<strong>[]</strong>表示是切片类型,<strong>{1,2,3}</strong>初始化gơ是1,2,3.其cap=len=3</li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s := arr[:]</code> <br />初始化切片s,是数larr的引?/li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s := arr[startIndex:endIndex]</code> <br />arr中从下标startIndex到endIndex-1 下的元素创徏Z个新的切?/li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s := arr[startIndex:]</code> <br />~省endIndex时将表示一直到arr的最后一个元?/li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s := arr[:endIndex]</code> <br />~省startIndex时将表示从arr的第一个元素开?/li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s1 := s[startIndex:endIndex]</code> <br />通过切片s初始化切片s1</li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s :=make([]int,len,cap)</code> <br />通过内置函数make()初始化切片s,[]int 标识为其元素cd为int的切?/li></ul><h4><a name="-3" style="color: rgb(119, 0, 0); text-decoration: none; display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0px; left: 0px; bottom: 0px;"></a>赋g使用</h4><p style="margin: 0px 0px 15px; line-height: 21px;">切片是引用类型,在用时需要注意其操作?a style="color: #770000; text-decoration: none;">查看CZ代码</a> Q?a style="color: #770000; text-decoration: none;">在线q行CZ代码</a> 切片可以通过内置函数append(slice []Type,elems ...Type)q加元素Qelems可以是一排typecd的数据,也可以是slice,因ؓq加的一个一个的元素Q因此如果将一个sliceq加到另一个slice中需要带?<strong>...</strong>"Q这h能表C是slice中的元素依次q加到另一个slice中。另外在通过下标讉K元素时下标不能超qlen大小Q如同数l的下标不能出len范围一栗?/p><ul style="margin-top: 15px; margin-right: 0px; margin-left: 45px; padding-left: 10px; margin-bottom: 0px !important;"><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s :=append(s,1,2,3,4)</code></li><li style="list-style: inherit;"><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-family: monospace, Monaco;">s :=append(s,s1...)</code></li></ul></div></div><div class="wmqeeuq" id="MySignature" style="margin-top: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal; background-color: #eeeedd;">转蝲时请注明出处Q老虞http://www.cnblogs.com/howDo/</div><img src ="http://www.aygfsteel.com/oathleo/aggbug/403973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oathleo/" target="_blank">oathleo</a> 2013-09-12 09:20 <a href="http://www.aygfsteel.com/oathleo/archive/2013/09/12/403973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Socket read writehttp://www.aygfsteel.com/oathleo/archive/2013/09/11/403935.htmloathleooathleoWed, 11 Sep 2013 00:56:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/09/11/403935.htmlhttp://www.aygfsteel.com/oathleo/comments/403935.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/09/11/403935.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/403935.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/403935.htmlq个时?read 要完_W一ơ没有read完,writeQ第二次read 到的仍然是上ơ没有read完的数据

oathleo 2013-09-11 08:56 发表评论
]]>
bufio ?/title><link>http://www.aygfsteel.com/oathleo/archive/2013/09/05/403714.html</link><dc:creator>oathleo</dc:creator><author>oathleo</author><pubDate>Thu, 05 Sep 2013 08:01:00 GMT</pubDate><guid>http://www.aygfsteel.com/oathleo/archive/2013/09/05/403714.html</guid><wfw:comment>http://www.aygfsteel.com/oathleo/comments/403714.html</wfw:comment><comments>http://www.aygfsteel.com/oathleo/archive/2013/09/05/403714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oathleo/comments/commentRss/403714.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oathleo/services/trackbacks/403714.html</trackback:ping><description><![CDATA[<div>// bufio 包实C带缓存的 I/O 操作</div><div>// 它封装一?io.Reader ?io.Writer 对象</div><div>// 使其h~存和一些文本读写功?/div><div></div><div>------------------------------------------------------------</div><div></div><div>// bufio.go</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Reader 实现了带~存?io.Reader 对象</div><div>type Reader struct {</div><div><span style="white-space:pre"> </span>// U有字段</div><div>}</div><div></div><div>// NewReaderSize ?rd 装成一个拥?size 大小~存?bufio.Reader 对象</div><div>// 如果 rd 的基cd是 bufio.Reader cdQ而且拥有_的缓?/div><div>// 则直接将 rd 转换为基cdq返?/div><div>func NewReaderSize(rd io.Reader, size int) *Reader</div><div></div><div>// NewReader 相当?NewReaderSize(rd, 4096)</div><div>func NewReader(rd io.Reader) *Reader</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Peek q回~存的一个切片,该切片引用缓存中?n 字节数据</div><div>// 该操作不会将数据dQ只是引?/div><div>// 引用的数据在下一ơ读取操作之前是有效?/div><div>// 如果引用的数据长度小?nQ则q回一个错误信?/div><div>// 如果 n 大于~存的d,则返?ErrBufferFull</div><div>// 通过 Peek 的返回|可以修改~存中的数据</div><div>// 但是不能修改底层 io.Reader 中的数据</div><div>func (b *Reader) Peek(n int) ([]byte, error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABCDEFG")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>b, _ := br.Peek(5)</div><div><span style="white-space:pre"> </span>fmt.Printf("%s\n", b)</div><div><span style="white-space:pre"> </span>// ABCDE</div><div></div><div><span style="white-space:pre"> </span>b[0] = 'a'</div><div><span style="white-space:pre"> </span>b, _ = br.Peek(5)</div><div><span style="white-space:pre"> </span>fmt.Printf("%s\n", b)</div><div><span style="white-space:pre"> </span>// aBCDE</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Read ?b 中读出数据到 p 中,q回d的字节数</div><div>// 如果 p 的大?>= ~存的d,而且~存不ؓI?/div><div>// 则只能读出缓存中的数据,不会从底?io.Reader 中提取数?/div><div>// 如果 p 的大?>= ~存的d,而且~存为空</div><div>// 则直接从底层 io.Reader ?p 中读出数据,不经q缓?/div><div>// 只有?b 中无可读数据Ӟ才返?(0, io.EOF)</div><div>func (b *Reader) Read(p []byte) (n int, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div><span style="white-space:pre"> </span>b := make([]byte, 20)</div><div></div><div><span style="white-space:pre"> </span>n, err := br.Read(b)</div><div><span style="white-space:pre"> </span>fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)</div><div><span style="white-space:pre"> </span>// ABCDEFGHIJKLMNOPQRST 20 <nil></div><div></div><div><span style="white-space:pre"> </span>n, err = br.Read(b)</div><div><span style="white-space:pre"> </span>fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)</div><div><span style="white-space:pre"> </span>// UVWXYZ1234567890     16 <nil> </div><div></div><div><span style="white-space:pre"> </span>n, err = br.Read(b)</div><div><span style="white-space:pre"> </span>fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)</div><div><span style="white-space:pre"> </span>//                      0  EOF</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadByte ?b 中读Z个字节ƈq回</div><div>// 如果 b 中无可读数据Q则q回一个错?/div><div>func (b *Reader) ReadByte() (c byte, err error)</div><div></div><div>// UnreadByte 撤消最后一ơ读出的字节</div><div>// 只有最后读出的字节可以被撤?/div><div>// 无论M操作Q只要有内容被读出,可以用 UnreadByte 撤消一个字?/div><div>func (b *Reader) UnreadByte() error</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABCDEFG")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>c, _ := br.ReadByte()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c\n", c)</div><div><span style="white-space:pre"> </span>// A</div><div></div><div><span style="white-space:pre"> </span>c, _ = br.ReadByte()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c\n", c)</div><div><span style="white-space:pre"> </span>// B</div><div></div><div><span style="white-space:pre"> </span>br.UnreadByte()</div><div><span style="white-space:pre"> </span>c, _ = br.ReadByte()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c\n", c)</div><div><span style="white-space:pre"> </span>// B</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadRune ?b 中读Z?UTF8 ~码的字Wƈq回</div><div>// 同时q回该字W的 UTF8 ~码长度</div><div>// 如果 UTF8 序列无法解码Z个正的 Unicode 字符</div><div>// 则只d b 中的一个字节,q返?U+FFFD 字符Qsize q回 1</div><div>func (b *Reader) ReadRune() (r rune, size int, err error)</div><div></div><div>// UnreadRune 撤消最后一ơ读出的 Unicode 字符</div><div>// 如果最后一ơ执行的不是 ReadRune 操作Q则q回一个错?/div><div>// 因此QUnreadRune ?UnreadByte 更严?/div><div>func (b *Reader) UnreadRune() error</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("你好Q世界!")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>c, size, _ := br.ReadRune()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c %v\n", c, size)</div><div><span style="white-space:pre"> </span>// ?3</div><div></div><div><span style="white-space:pre"> </span>c, size, _ = br.ReadRune()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c %v\n", c, size)</div><div><span style="white-space:pre"> </span>// ?3</div><div></div><div><span style="white-space:pre"> </span>br.UnreadRune()</div><div><span style="white-space:pre"> </span>c, size, _ = br.ReadRune()</div><div><span style="white-space:pre"> </span>fmt.Printf("%c %v\n", c, size)</div><div><span style="white-space:pre"> </span>// ?3</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Buffered q回~存中数据的长度</div><div>func (b *Reader) Buffered() int</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("你好Q世界!")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>fmt.Println(br.Buffered())</div><div><span style="white-space:pre"> </span>// 0</div><div></div><div><span style="white-space:pre"> </span>br.Peek(1)</div><div><span style="white-space:pre"> </span>fmt.Println(br.Buffered())</div><div><span style="white-space:pre"> </span>// 18</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadSlice ?b 中查?delim q返?delim 及其之前的所有数据的切片</div><div>// 该操作会d数据Q返回的切片是已d数据的引?/div><div>// 切片中的数据在下一ơ读取操作之前是有效?/div><div>//</div><div>// 如果 ReadSlice 在找?delim 之前遇到错误</div><div>// 则读出缓存中的所有数据ƈq回Q同时返回遇到的错误Q通常?io.EOFQ?/div><div>// 如果在整个缓存中都找不到 delimQ则 err q回 ErrBufferFull</div><div>// 如果 ReadSlice 能找?delimQ则 err 始终q回 nil</div><div>//</div><div>// 因ؓq回的切片中的数据有可能被下一ơ读写操作修?/div><div>// 因此大多数操作应该?ReadBytes ?ReadStringQ它们返回的不是数据引用</div><div>func (b *Reader) ReadSlice(delim byte) (line []byte, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC DEF GHI JKL")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>w, _ := br.ReadSlice(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "ABC "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadSlice(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "DEF "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadSlice(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "GHI "</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadLine 是一个低U的原始的行d操作</div><div>// 大多数情况下Q应该?ReadBytes('\n') ?ReadString('\n')</div><div>// 或者用一?Scanner</div><div>//</div><div>// ReadLine 通过调用 ReadSlice Ҏ实现Q返回的也是~存的切?/div><div>// ReadLine 试q回一个单行数据,不包括行标讎ͼ\n ?\r\nQ?/div><div>// 如果在缓存中找不到行标讎ͼ则设|?isPrefix ?trueQ表C查找未完成</div><div>// 同时d~存中的数据q作为切片返?/div><div>// 只有在当前缓存中扑ֈ行尾标记Q才?isPrefix 讄?falseQ表C查扑֮?/div><div>// 可以多次调用 ReadLine 来读Z?/div><div>// q回的数据在下一ơ读取操作之前是有效?/div><div>// 如果 ReadLine 无法获取M数据Q则q回一个错误信息(通常?io.EOFQ?/div><div>func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC\nDEF\r\nGHI\r\nJKL")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>w, isPrefix, _ := br.ReadLine()</div><div><span style="white-space:pre"> </span>fmt.Printf("%q %v\n", w, isPrefix)</div><div><span style="white-space:pre"> </span>// "ABC" false</div><div></div><div><span style="white-space:pre"> </span>w, isPrefix, _ = br.ReadLine()</div><div><span style="white-space:pre"> </span>fmt.Printf("%q %v\n", w, isPrefix)</div><div><span style="white-space:pre"> </span>// "DEF" false</div><div></div><div><span style="white-space:pre"> </span>w, isPrefix, _ = br.ReadLine()</div><div><span style="white-space:pre"> </span>fmt.Printf("%q %v\n", w, isPrefix)</div><div><span style="white-space:pre"> </span>// "GHI" false</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadBytes ?b 中查?delim q读?delim 及其之前的所有数?/div><div>// 如果 ReadBytes 在找?delim 之前遇到错误</div><div>// 则返回遇到错误之前的所有数据,同时q回遇到的错误(通常?io.EOFQ?/div><div>// 只有?ReadBytes 找不?delim Ӟerr 才不?nil</div><div>// 对于单的用途,使用 Scanner 可能更方?/div><div>func (b *Reader) ReadBytes(delim byte) (line []byte, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC DEF GHI JKL")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>w, _ := br.ReadBytes(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "ABC "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadBytes(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "DEF "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadBytes(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "GHI "</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadString 功能?ReadBytesQ只不过q回的是一个字W串</div><div>func (b *Reader) ReadString(delim byte) (line string, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC DEF GHI JKL")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div></div><div><span style="white-space:pre"> </span>w, _ := br.ReadString(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "ABC "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadString(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "DEF "</div><div></div><div><span style="white-space:pre"> </span>w, _ = br.ReadString(' ')</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", w)</div><div><span style="white-space:pre"> </span>// "GHI "</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// WriteTo 实现?io.WriterTo 接口</div><div>func (b *Reader) WriteTo(w io.Writer) (n int64, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABCEFG")</div><div><span style="white-space:pre"> </span>br := bufio.NewReader(s)</div><div><span style="white-space:pre"> </span>b := bytes.NewBuffer(make([]byte, 0))</div><div></div><div><span style="white-space:pre"> </span>br.WriteTo(b)</div><div><span style="white-space:pre"> </span>fmt.Printf("%s\n", b)</div><div><span style="white-space:pre"> </span>// ABCEFG</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Writer 实现了带~存?io.Writer 对象</div><div>// 如果在向 Writer 中写入数据的q程中遇到错?/div><div>// ?Writer 不会再接受Q何数?/div><div>// 而且后箋的写入操作都返回错误信?/div><div>type Writer struct {</div><div><span style="white-space:pre"> </span>// U有字段</div><div>}</div><div></div><div>// NewWriterSize ?wr 装成一个拥?size 大小~存?bufio.Writer 对象</div><div>// 如果 wr 的基cd是 bufio.Writer cdQ而且拥有_的缓?/div><div>// 则直接将 wr 转换为基cdq返?/div><div>func NewWriterSize(wr io.Writer, size int) *Writer</div><div></div><div>// NewWriter 相当?NewWriterSize(wr, 4096)</div><div>func NewWriter(wr io.Writer) *Writer</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Flush 缓存中的数据提交到底层?io.Writer ?/div><div>func (b *Writer) Flush() error</div><div></div><div>// Available q回~存中的可以I间</div><div>func (b *Writer) Available() int</div><div></div><div>// Buffered q回~存中未提交的数据长?/div><div>func (b *Writer) Buffered() int</div><div></div><div>// Write ?p 中的数据写入 b 中,q回写入的字节数</div><div>// 如果写入的字节数于 p 的长度,则返回一个错误信?/div><div>func (b *Writer) Write(p []byte) (nn int, err error)</div><div></div><div>// WriteString ?WriteQ只不过写入的是字符?/div><div>func (b *Writer) WriteString(s string) (int, error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>b := bytes.NewBuffer(make([]byte, 0))</div><div><span style="white-space:pre"> </span>bw := bufio.NewWriter(b)</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Available()) // 4096</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Buffered())  // 0</div><div></div><div><span style="white-space:pre"> </span>bw.WriteString("ABCDEFGH")</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Available()) // 4088</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Buffered())  // 8</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", b)       // ""</div><div></div><div><span style="white-space:pre"> </span>bw.Flush()</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Available()) // 4096</div><div><span style="white-space:pre"> </span>fmt.Println(bw.Buffered())  // 0</div><div><span style="white-space:pre"> </span>fmt.Printf("%q\n", b)       // "ABCEFG"</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// WriteByte ?b 中写入一个字?/div><div>func (b *Writer) WriteByte(c byte) error</div><div></div><div>// WriteRune ?b 中写?r ?UTF8 ~码</div><div>// q回 r 的编码长?/div><div>func (b *Writer) WriteRune(r rune) (size int, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>b := bytes.NewBuffer(make([]byte, 0))</div><div><span style="white-space:pre"> </span>bw := bufio.NewWriter(b)</div><div><span style="white-space:pre"> </span>bw.WriteByte('H')</div><div><span style="white-space:pre"> </span>bw.WriteByte('e')</div><div><span style="white-space:pre"> </span>bw.WriteByte('l')</div><div><span style="white-space:pre"> </span>bw.WriteByte('l')</div><div><span style="white-space:pre"> </span>bw.WriteByte('o')</div><div><span style="white-space:pre"> </span>bw.WriteByte(' ')</div><div><span style="white-space:pre"> </span>bw.WriteRune('?)</div><div><span style="white-space:pre"> </span>bw.WriteRune('?)</div><div><span style="white-space:pre"> </span>bw.WriteRune('Q?)</div><div><span style="white-space:pre"> </span>bw.Flush()</div><div><span style="white-space:pre"> </span>fmt.Println(b) // Hello 世界Q?/div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadFrom 实现?io.ReaderFrom 接口</div><div>func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>b := bytes.NewBuffer(make([]byte, 0))</div><div><span style="white-space:pre"> </span>s := strings.NewReader("Hello 世界Q?)</div><div><span style="white-space:pre"> </span>bw := bufio.NewWriter(b)</div><div><span style="white-space:pre"> </span>bw.ReadFrom(s)</div><div><span style="white-space:pre"> </span>bw.Flush()</div><div><span style="white-space:pre"> </span>fmt.Println(b) // Hello 世界Q?/div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ReadWriter 集成?bufio.Reader ?bufio.Writer</div><div>// 它实C io.ReadWriter 接口</div><div>type ReadWriter struct {</div><div><span style="white-space:pre"> </span>*Reader</div><div><span style="white-space:pre"> </span>*Writer</div><div>}</div><div></div><div>// NewReadWriter 装 r ?w Z?bufio.ReadWriter 对象</div><div>func NewReadWriter(r *Reader, w *Writer) *ReadWriter</div><div></div><div>------------------------------------------------------------</div><div></div><div>// scan.go</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Scanner 提供了一个方便的接口来读取数据,例如d一个多行文?/div><div>// q箋调用 Scan Ҏ扫描数据中?#8220;指定部分”Q蟩q各?#8220;指定部分”之间的数?/div><div>// Scanner 使用了缓存,所?#8220;指定部分”的长度不能超出缓存的长度</div><div>// Scanner 需要一?SplitFunc cd?#8220;切分函数”来确?#8220;指定部分”的格?/div><div>// 本包中提供的“切分函数”?#8220;行切分函?#8221;?#8220;字节切分函数”?#8220;UTF8字符~码切分函数”</div><div>// ?#8220;单词切分函数”Q用户也可以自定?#8220;切分函数”</div><div>// 默认?#8220;切分函数”?#8220;行切分函?#8221;Q用于获取数据中的一行数据(不包括行Q?/div><div>//</div><div>// 扫描在遇C面的情况时会停止Q?/div><div>// 1、数据扫描完毕,遇到 io.EOF</div><div>// 2、遇到读写错?/div><div>// 3?#8220;指定部分”的长度超q了~存的长?/div><div>// 如果要对数据q行更多的控Ӟ比如的错误处理或扫描更大?#8220;指定部分”或顺序扫?/div><div>// 则应该?bufio.Reader</div><div>type Scanner struct {</div><div><span style="white-space:pre"> </span>// U有字段</div><div>}</div><div></div><div>// SplitFunc 用来定义“切分函数”cd</div><div>// data 是要扫描的数?/div><div>// atEOF 标记底层 io.Reader 中的数据是否已经d</div><div>// advance q回 data 中已处理的数据长?/div><div>// token q回扑ֈ?#8220;指定部分”</div><div>// err q回错误信息</div><div>// 如果?data 中无法找C个完整的“指定部分”</div><div>// ?SplitFunc q回 (0, nil) 来告?Scanner</div><div>// 向缓存中填充更多数据Q然后再ơ扫?/div><div>//</div><div>// 如果q回?err 是非 nil |扫描被l止Qƈq回错误信息</div><div>//</div><div>// 如果 data 为空Q则“切分函数”不被调?/div><div>// 意思是?SplitFunc 中不必考虑 data 为空的情?/div><div>//</div><div>// SplitFunc 的作用很单,?data 中找Z感兴的数据Q然后返?/div><div>// q告诉调用者,data 中有多少数据你已l处理过?/div><div>type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)</div><div></div><div>// NewScanner 创徏一?Scanner 来扫?r</div><div>// 默认切分函数?ScanLines</div><div>func NewScanner(r io.Reader) *Scanner</div><div></div><div>// Err q回扫描q程中遇到的?EOF 错误</div><div>// 供用戯用,以便获取错误信息</div><div>func (s *Scanner) Err() error</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Bytes 最后一ơ扫描出?#8220;指定部分”作ؓ一个切片返回(引用传递)</div><div>// 下一ơ的 Scan 操作会覆盖本ơ返回的l果</div><div>func (s *Scanner) Bytes() []byte</div><div></div><div>// Text 最后一ơ扫描出?#8220;指定部分”作ؓ字符串返回(g递)</div><div>func (s *Scanner) Text() string</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Scan ?Scanner 的数据中扫描“指定部分”</div><div>// 扑ֈ后,用户可以通过 Bytes ?Text Ҏ来取?#8220;指定部分”</div><div>// 如果扫描q程中遇到错误,则终止扫描,q返?false</div><div>func (s *Scanner) Scan() bool</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC\nDEF\r\nGHI\nJKL")</div><div><span style="white-space:pre"> </span>bs := bufio.NewScanner(s)</div><div><span style="white-space:pre"> </span>for bs.Scan() {</div><div><span style="white-space:pre"> </span>fmt.Printf("%s %v\n", bs.Bytes(), bs.Text())</div><div><span style="white-space:pre"> </span>}</div><div><span style="white-space:pre"> </span>// ABC ABC</div><div><span style="white-space:pre"> </span>// DEF DEF</div><div><span style="white-space:pre"> </span>// GHI GHI</div><div><span style="white-space:pre"> </span>// JKL JKL</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// Split 用于讄 Scanner ?#8220;切分函数”</div><div>// q个函数必须在调?Scan 前执?/div><div>func (s *Scanner) Split(split SplitFunc)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("ABC DEF GHI JKL")</div><div><span style="white-space:pre"> </span>bs := bufio.NewScanner(s)</div><div><span style="white-space:pre"> </span>bs.Split(bufio.ScanWords)</div><div><span style="white-space:pre"> </span>for bs.Scan() {</div><div><span style="white-space:pre"> </span>fmt.Println(bs.Text())</div><div><span style="white-space:pre"> </span>}</div><div><span style="white-space:pre"> </span>// ABC</div><div><span style="white-space:pre"> </span>// DEF</div><div><span style="white-space:pre"> </span>// GHI</div><div><span style="white-space:pre"> </span>// JKL</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ScanBytes 是一?#8220;切分函数”</div><div>// 用来扑և data 中的单个字节q返?/div><div>func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("Hello 世界Q?)</div><div><span style="white-space:pre"> </span>bs := bufio.NewScanner(s)</div><div><span style="white-space:pre"> </span>bs.Split(bufio.ScanBytes)</div><div><span style="white-space:pre"> </span>for bs.Scan() {</div><div><span style="white-space:pre"> </span>fmt.Printf("%s ", bs.Text())</div><div><span style="white-space:pre"> </span>}</div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ScanRunes 是一?#8220;切分函数”</div><div>// 用来扑և data 中的单个 UTF8 字符的编码ƈq回</div><div>// 如果 UTF8 解码出错Q则q回?U+FFFD 会被做ؓ "\xef\xbf\xbd" q回</div><div>// q得用h法区?#8220;真正的U+FFFD字符”?#8220;解码错误的返回?#8221;</div><div>func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)</div><div></div><div>func main() {</div><div><span style="white-space:pre"> </span>s := strings.NewReader("Hello 世界Q?)</div><div><span style="white-space:pre"> </span>bs := bufio.NewScanner(s)</div><div><span style="white-space:pre"> </span>bs.Split(bufio.ScanRunes)</div><div><span style="white-space:pre"> </span>for bs.Scan() {</div><div><span style="white-space:pre"> </span>fmt.Printf("%s ", bs.Text())</div><div><span style="white-space:pre"> </span>} // H e l l o   ??Q?/div><div>}</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ScanLines 是一?#8220;切分函数”</div><div>// 用来扑և data 中的单行数据q返回(包括IQ?/div><div>// 行尾标记可能?\n ?\r\nQ返回g包括行尾标记Q?/div><div>func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)</div><div></div><div>------------------------------------------------------------</div><div></div><div>// ScanWords 是一?#8220;切分函数”</div><div>// 用来扑և data 中的单词</div><div>// 单词以空白字W分隔,I白字符?unicode.IsSpace 定义</div><div>func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)</div><div></div><img src ="http://www.aygfsteel.com/oathleo/aggbug/403714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oathleo/" target="_blank">oathleo</a> 2013-09-05 16:01 <a href="http://www.aygfsteel.com/oathleo/archive/2013/09/05/403714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang cd转换整理http://www.aygfsteel.com/oathleo/archive/2013/08/30/403491.htmloathleooathleoFri, 30 Aug 2013 03:37:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/30/403491.htmlhttp://www.aygfsteel.com/oathleo/comments/403491.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/30/403491.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/403491.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/403491.html 

Golang cd转换整理

分类Q?nbsp;Go2013-07-31 11:02 177人阅?/span> 评论(0) 收藏 举报
1、整形到字符Ԍ
    
  1. var i int = 1  
  2. var s string  
  1. s = strconv.Itoa(i) 或?nbsp;s = FormatInt(int64(i), 10)  

2、字W串到整?br />    
  1. var s string = "1"  
  2. var i int  
  3. i, err = strconv.Atoi(s) 或?nbsp;i, err = ParseInt(s, 10, 0)  

3、字W串到float(32 / 64)
    
  1. var s string = 1  
  2. var f float32  
  3. f, err = ParseFloat(s, 32)  


 float 64的时候将上面函数中的32转ؓ64卛_


4、整形到float或者float到整?br />    直接使用float(i) 或?int(f) 直接q行转换卛_


oathleo 2013-08-30 11:37 发表评论
]]>golang strconvhttp://www.aygfsteel.com/oathleo/archive/2013/08/30/403488.htmloathleooathleoFri, 30 Aug 2013 03:26:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/30/403488.htmlhttp://www.aygfsteel.com/oathleo/comments/403488.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/30/403488.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/403488.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/403488.html

golang strconv

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


a:=strconv.FormatFloat(10.100,'f',-1,32)

输出:

10.1

a := strconv.FormatFloat(10.101, 'f', -1, 64)

输出:

10.101

a := strconv.FormatFloat(10.010, 'f', -1, 64)

输出Q?0.01

a:=strconv.FormatFloat(10.1,'f',2,64)

输出:10.10


f 参数可以时e,E,g,G

-1 代表输出的精度小数点后的位数Q如果是<0的|则返回最的位数来表C敎ͼ如果是大?的则q回对应位数的?/p>

64 为float的类型,go中float分ؓ32?4位,因此需要传?2或?4


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


golang strconv.ParseInt 是将字符串{换ؓ数字的函?功能灰常之强?看的我口水直?

func ParseInt(s string, base int, bitSize int) (i int64, err error)

参数1 数字的字W串形式

参数2 数字字符串的q制 比如二进?nbsp;八进?nbsp;十进?nbsp;十六q制

参数3 q回l果的bit大小 也就是int8 int16 int32 int64

代码:

01package main
02     
03import (
04    "strconv"
05)
06     
07func main() {
08    i, err := strconv.ParseInt("123", 10, 32)
09    if err != nil {
10        panic(err)
11    }
12    println(i)
13}




oathleo 2013-08-30 11:26 发表评论
]]>Pragma: no-cache Ҏ能的媄?/title><link>http://www.aygfsteel.com/oathleo/archive/2013/08/27/403367.html</link><dc:creator>oathleo</dc:creator><author>oathleo</author><pubDate>Tue, 27 Aug 2013 07:29:00 GMT</pubDate><guid>http://www.aygfsteel.com/oathleo/archive/2013/08/27/403367.html</guid><wfw:comment>http://www.aygfsteel.com/oathleo/comments/403367.html</wfw:comment><comments>http://www.aygfsteel.com/oathleo/archive/2013/08/27/403367.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oathleo/comments/commentRss/403367.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oathleo/services/trackbacks/403367.html</trackback:ping><description><![CDATA[做了下go和java的http性能的简单比?br />服务端直接输出字W串<br />使用JMeter<br />windows?br /> <img src="file:///C:/Users/Leo/AppData/Roaming/Foxmail/FoxmailTemp(2)/Catch2C57.jpg" alt="" /><img src="http://www.aygfsteel.com/images/blogjava_net/oathleo/1.jpg" border="0" alt="" width="1023" height="87" /><br /><br /><img src="http://www.aygfsteel.com/images/blogjava_net/oathleo/2.jpg" border="0" alt="" width="1014" height="77" /><br /><br />2000的ƈ发,试l果很出乎意料,go不会q么差吧<br /><br /><br />研究了半时Q原因如?br />tomcat的servlet里加?span style="background-color: #eeeeee; font-size: 13px;">        response.setHeader(</span><span style="background-color: #eeeeee; font-size: 13px;">"</span><span style="background-color: #eeeeee; font-size: 13px;">Pragma</span><span style="background-color: #eeeeee; font-size: 13px;">"</span><span style="background-color: #eeeeee; font-size: 13px;">, </span><span style="background-color: #eeeeee; font-size: 13px;">"</span><span style="background-color: #eeeeee; font-size: 13px;">no-cache</span><span style="background-color: #eeeeee; font-size: 13px;">"</span><span style="background-color: #eeeeee; font-size: 13px;">);<br /></span>go里没有设|该参数<br /><br />讄后重新跑试<br /><img src="http://www.aygfsteel.com/images/blogjava_net/oathleo/33.jpg" border="0" alt="" width="1021" height="84" /><br /><br /><br />可以了吧<br /><br /><br /><br /><br /><img src ="http://www.aygfsteel.com/oathleo/aggbug/403367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oathleo/" target="_blank">oathleo</a> 2013-08-27 15:29 <a href="http://www.aygfsteel.com/oathleo/archive/2013/08/27/403367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>golang html ?golang客户?上传文g 转蝲http://www.aygfsteel.com/oathleo/archive/2013/08/27/403336.htmloathleooathleoTue, 27 Aug 2013 01:10:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/27/403336.htmlhttp://www.aygfsteel.com/oathleo/comments/403336.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/27/403336.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/403336.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/403336.htmlgolang html ?golang客户?上传文g
 May 30 , 2013 at 08:30 am -  263点击 -  0 评论

文件上?/span>

 var buffer bytes.Buffer

w := multipart.NewWriter(&buffer)
// Write fields and files
w.CreateFormField("input1")
w.WriteField(
"input1","value1")
w.CreateFormFile(
"file","filename.dat")

resp,err :
= http.Post(url,w.FormDataContentType(),&buffer)


服务器的handler:

func uploadHandler(w http.ResponseWriter, r 
*http.Request){

 
if r.URL.Path=="/upload.go" {   

        fn,header,err:
=r.FormFile("file")

        defer fn.Close()

        f,err:
=os.Create("filenametosaveas")

        defer f.Close()

        io.Copy(f,fn)

    }

}


客户端代码:
func Upload() (err error) {

    
// Create buffer

    buf :
= new(bytes.Buffer) // caveat IMO dont use this for large files, \

    
// create a tmpfile and assemble your multipart from there (not tested)

    w :
= multipart.NewWriter(buf)

    
// Create file field

    fw, err :
= w.CreateFormFile("file""helloworld.go"//q里的file很重要,必须和服务器端的FormFile一?/span>

    
if err != nil {

        fmt.Println(
"c")

        
return err

    }

    fd, err :
= os.Open("helloworld.go")

    
if err != nil {

        fmt.Println(
"d")

        
return err

    }

    defer fd.Close()

    
// Write file field from file to upload

    _, err 
= io.Copy(fw, fd)

    
if err != nil {

        fmt.Println(
"e")

        
return err

    }

    
// Important if you do not close the multipart writer you will not have a

    
// terminating boundry

    w.Close()

    req, err :
= http.NewRequest("POST","http://192.168.2.127/configure.go?portId=2", buf)

    
if err != nil {

        fmt.Println(
"f")

        
return err

    }

    req.Header.Set(
"Content-Type", w.FormDataContentType())

      var client http.Client

    res, err :
= client.Do(req)

    
if err != nil {

        fmt.Println(
"g")

        
return err

    }

    io.Copy(os.Stderr, res.Body) 
// Replace this with Status.Code check

    fmt.Println(
"h")

    
return err

}


html上传Q?a style="color: #1570a6; text-decoration: none;">原文

package main

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

// 获取大小的接?/span>
type Sizer interface {
    Size() int64
}

// hello world, the web server
func HelloServer(w http.ResponseWriter, r *http.Request) {
    
if "POST" == r.Method {
        file, _, err :
= r.FormFile("file")
        
if err != nil {
            http.Error(w, err.Error(), 
500)
            
return
        }
        defer file.Close()
        f,err:
=os.Create("filenametosaveas")
        defer f.Close()
        io.Copy(f,file)
        fmt.Fprintf(w, 
"上传文g的大ؓ: %d", file.(Sizer).Size())
        
return
    }

    
// 上传面
    w.Header().Add("Content-Type""text/html")
    w.WriteHeader(
200)
    html :
= `
<form enctype="multipart/form-data" action="/hello" method="POST">
    Send 
this file: <input name="file" type="file" />
    
<input type="submit" value="Send File" />
</form>
`
    io.WriteString(w, html)
}

func main() {
    http.HandleFunc(
"/hello", HelloServer)
    err :
= http.ListenAndServe(":12345", nil)
    
if err != nil {
        log.Fatal(
"ListenAndServe: ", err)
    }
}



大文件上?/span>

关键的不同是io.MultiReader

package main 

import ( 
  
"fmt" 
  
"net/http" 
  
"mime/multipart" 
  
"bytes" 
  
"os" 
  
"io" 
  ) 


func postFile(filename 
string, target_url string) (*http.Response, error) { 
  body_buf :
= bytes.NewBufferString(""
  body_writer :
= multipart.NewWriter(body_buf) 

  
// use the body_writer to write the Part headers to the buffer 
  _, err := body_writer.CreateFormFile("upfile", filename) 
  
if err != nil { 
    fmt.Println(
"error writing to buffer"
    
return nil, err 
  } 

  
// the file data will be the second part of the body 
  fh, err := os.Open(filename) 
  
if err != nil { 
    fmt.Println(
"error opening file"
    
return nil, err 
  } 
  defer fh.Close()
  
// need to know the boundary to properly close the part myself. 
  boundary := body_writer.Boundary()
  close_string :
= fmt.Sprintf("\r\n--%s--\r\n", boundary)
  close_buf :
= bytes.NewBufferString(close_string)
  
// use multi-reader to defer the reading of the file data until writing to the socket buffer. 
  request_reader := io.MultiReader(body_buf, fh, close_buf) 
  fi, err :
= fh.Stat() 
  
if err != nil { 
    fmt.Printf(
"Error Stating file: %s", filename) 
    
return nil, err 
  } 
  req, err :
= http.NewRequest("POST", target_url, request_reader) 
  
if err != nil { 
    
return nil, err 
  } 

  
// Set headers for multipart, and Content Length 
  req.Header.Add("Content-Type""multipart/form-data; boundary=" + boundary) 
  req.ContentLength 
= fi.Size()+int64(body_buf.Len())+int64(close_buf.Len()) 

  
return http.DefaultClient.Do(req) 
}





oathleo 2013-08-27 09:10 发表评论
]]>
golang string rune len 可能不同http://www.aygfsteel.com/oathleo/archive/2013/08/19/403027.htmloathleooathleoMon, 19 Aug 2013 03:31:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/19/403027.htmlhttp://www.aygfsteel.com/oathleo/comments/403027.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/19/403027.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/403027.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/403027.html        rune_str := []rune(info)
        fmt.Print("rune_len:" , len(rune_str))
        fmt.Print("string_len:" , len(info))

string 和对应的 rune数组的len不一定相?/div>
如果info是有中文的,则两个length是不一LQ做string处理的时候,要注?br />

oathleo 2013-08-19 11:31 发表评论
]]>golang xml 处理之生?属性必d?/title><link>http://www.aygfsteel.com/oathleo/archive/2013/08/16/402934.html</link><dc:creator>oathleo</dc:creator><author>oathleo</author><pubDate>Fri, 16 Aug 2013 07:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/oathleo/archive/2013/08/16/402934.html</guid><wfw:comment>http://www.aygfsteel.com/oathleo/comments/402934.html</wfw:comment><comments>http://www.aygfsteel.com/oathleo/archive/2013/08/16/402934.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oathleo/comments/commentRss/402934.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oathleo/services/trackbacks/402934.html</trackback:ping><description><![CDATA[xml对应的struct 属性必d写,否则无法实现Q?br /> Code是必ȝ<br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->package main<br /> <br /> import (<br />     "encoding/xml"<br />     "fmt"<br />     "os"<br /> )<br /> <br /> type xmldas <span style="color: #0000FF; ">struct</span> {<br />     XMLName  xml.Name       `xml:"das"`<br />     DataPort <span style="color: #0000FF; ">string</span>         `xml:"DataPort,attr"`<br />     Desc     <span style="color: #0000FF; ">string</span>         `xml:"desc,attr"`<br />     Src      xmlsource      `xml:"source"`<br />     Dest     xmldestination `xml:"destination"`<br /> }<br /> <br /> type xmlsource <span style="color: #0000FF; ">struct</span> {<br />     Path  <span style="color: #0000FF; ">string</span> `xml:"path,attr"`<br />     Param <span style="color: #0000FF; ">string</span> `xml:"param,attr"`<br /> }<br /> <br /> type xmldestination <span style="color: #0000FF; ">struct</span> {<br />     Path  <span style="color: #0000FF; ">string</span> `xml:"path,attr"`<br />     Param <span style="color: #0000FF; ">string</span> `xml:"param,attr"`<br /> }<br /> <br /> func main() {<br />     v := xmldas{DataPort: "8250", Desc: "123"}<br />     v.Src = xmlsource{Path: "123", Param: "456"}<br />     v.Dest = xmldestination{Path: "789", Param: "000"}<br />     output, err := xml.MarshalIndent(v, "  ", "    ")<br />     <span style="color: #0000FF; ">if</span> err != nil {<br />         fmt.Printf("error: %v\n", err)<br />     }<br />     os.Stdout.Write([]<span style="color: #0000FF; ">byte</span>(xml.Header))<br />     os.Stdout.Write(output)<br /> }</div><img src ="http://www.aygfsteel.com/oathleo/aggbug/402934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oathleo/" target="_blank">oathleo</a> 2013-08-16 15:53 <a href="http://www.aygfsteel.com/oathleo/archive/2013/08/16/402934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>golang xml 处理http://www.aygfsteel.com/oathleo/archive/2013/08/12/402704.htmloathleooathleoMon, 12 Aug 2013 09:03:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/12/402704.htmlhttp://www.aygfsteel.com/oathleo/comments/402704.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/12/402704.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/402704.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/402704.htmlxml文g解析成对应的struct对象是通过xml.Unmarshal来完成的Q这个过E是如何实现的?可以看到我们的struct定义后面多了一些类gxml:"serverName"q样的内?q个是struct的一个特性,它们被称?struct tagQ它们是用来辅助反射的?br />

package main

import (
    "encoding/xml"
    "fmt"
    "os"
)

type Servers struct {
    XMLName xml.Name `xml:"servers"`
    Version string   `xml:"version,attr"`
    Svs     []server `xml:"server"`
}

type server struct {
    ServerName string `xml:"serverName"`
    ServerIP   string `xml:"serverIP"`
}

func main() {
    v := &Servers{Version: "1"}
    v.Svs = append(v.Svs, server{"Shanghai_VPN", "127.0.0.1"})
    v.Svs = append(v.Svs, server{"Beijing_VPN", "127.0.0.2"})
    output, err := xml.MarshalIndent(v, "  ", "    ")
    if err != nil {
        fmt.Printf("error: %v\n", err)
    }
    os.Stdout.Write([]byte(xml.Header))

    os.Stdout.Write(output)
}




oathleo 2013-08-12 17:03 发表评论
]]>
exec starthttp://www.aygfsteel.com/oathleo/archive/2013/08/08/402538.htmloathleooathleoThu, 08 Aug 2013 01:07:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/08/402538.htmlhttp://www.aygfsteel.com/oathleo/comments/402538.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/08/402538.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/402538.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/402538.htmlexec卡住了,d调用肯定卡住?br />调用Start

func (*Cmd) Run
func (c *Cmd) Run() error

Run starts the specified command and waits for it to complete.

The returned error is nil if the command runs, has no problems copying stdin, stdout, and stderr, and exits with a zero exit status.

If the command fails to run or doesn't complete successfully, the error is of type *ExitError. Other error types may be returned for I/O problems.

func (*Cmd) Start

func (c *Cmd) Start() error

Start starts the specified command but does not wait for it to complete.



oathleo 2013-08-08 09:07 发表评论
]]>
Golang语法与代码格式速记http://www.aygfsteel.com/oathleo/archive/2013/08/02/402316.htmloathleooathleoFri, 02 Aug 2013 08:15:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402316.htmlhttp://www.aygfsteel.com/oathleo/comments/402316.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402316.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/402316.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/402316.html
// Description: Golang语法与代码格式速记
// Author: cxy
// Date: 2013-04-01
// Version: 0.3
// TODO 说明


// TODO package

// Go是采用语法解析器自动在每行末֢加分P所以在写代码的时候可以把分号省略?br />// Go~程中只有几个地斚w要手工增加分P? for循环使用分号把初始化Q条件和遍历元素分开。在一行中有多条语句时Q需要增加分受?br />// 不能把控制语?if, for, switch, or select)、函数、方?nbsp;的左大括号单独放在一行, 如果你这样作了语法解析器会在大括号之前插入一个分PD~译错误?br />
// 引用包名与导入\径的最后一个目录一?/span>
import "fmt"
import "math/rand"
fmt.Println(rand.Intn(10))    // 0?0之间的非负伪随机?br />
// 用圆括号l合导入包,q是“factored”导入语句
import ("fmt"; "math")
import (
    "fmt"
    "math"
)
// 导入包可以定义别名,防止同名U的包冲H?/span>
import n "net/http"
import (
    控制?nbsp;"fmt"
    m "math"
)
控制?Println(m.Pi)

// 首字母大写的名称是被导出? 首字母小写的名称只能在同一包内讉K(同包跨文件也能访?
var In int // In is public
var in byte // in is private
var 看不?nbsp;string // 看不?nbsp;is private
const Com bool = false // Com is public
const q是看不?nbsp;uint8 = 1 // q是看不?nbsp;is private
type Integer int // Integer is public
type ブーリア?nbsp;*bool // ブーリア?nbsp;is private
func Export() {// Export is public
func 导入() {// 导入 is private
func (me *Integer) valueOf(s stringint {// valueOf is private
func (i ブーリア? String() string {// String is public

// Go 的基本类型:
┌──────┬─────────┬────────┬─────────┬───────────┬────────────┐
│ bool │ string  │        │         │           │            │
├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
│ int  │ int8    │ int16  │ int32   │ int64     │            │
│      │         │        │ rune    │           │            │
├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
│ uint │ uint8   │ uint16 │ uint32  │ uint64    │ uintptr    │
│      │ byte    │        │         │           │            │
├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
│      │         │        │ float32 │ float64   │            │
├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
│      │         │        │         │ complex64 │ complex128 │
└──────┴─────────┴────────┴─────────┴───────────┴────────────┘
// byte ?nbsp;uint8 的别?br />// rune ?nbsp;int32 的别名,代表一个Unicode码点

// 变量声明, 使用var关键?nbsp;   (Go中只能用var声明变量Q无需昑ּ初始化|
var i int    // i = 0
var s string    // s = ""    (Go中的string不存在nil(null)|默认零值就是空?nbsp;"" ?nbsp;``)
var e error    // e = nil, error是Go的内建接口类型,不是基本cd?br />
// var 语句声明了一个变量的列表Q类型在变量名之?/span>
var a,b,c int    // a = 0, b = 0, c = 0
var (
    a int    // a = 0
    b string    // b = ""
    c uint    // c = 0
)

// 变量定义时初始化赋|每个变量对应一个?/span>
var a int = 0
var a,b int = 0, 1

// 初始化用表辑ּӞ可以省略cdQ变量从初始g获得cd
var a = 'A'    // a int32
c := 1 + 2i    // c complex128
var a,b = 0, "B"    // a int, b string
a, b := 0, "B"    // a int, b string
c := `formatted
 string`    // c string

// := l构不能使用在函数外Q函数外的每个语法块都必M关键字开?br />
// 帔R可以是字W、字W串、布或数字cd的|数值常量是高精度的?/span>
const x int = 3
const (
    a byte = 'A'
    b string = "B"
    c bool = true
    d int = 4
    e float32 = 5.1
    f complex64 = 6 + 6i
)

// 未指定类型的帔R由常量值决定其cd
const a = 0    // a int
const (
    b = 2.3    // b float64
    c = true    // c bool
)

// 自动枚D帔R iota
// iota的枚丑ր可以赋值给数值兼容类?br />// 每个帔R单独声明? iota不会自动递增(无意?
const a int = iota    // a = 0
const b int = iota    // b = 0
const c byte = iota    // c = 0
const d uint64 = iota    // d = 0

// 帔Rl合声明? iota每次引用会逐步自增, 初始gؓ0,步进gؓ1
const (
    a uint8 = iota    // a = 0
    b int16 = iota    // b = 1
    c rune = iota    // c = 2
    d float64 = iota    // d = 3
    e uintptr = iota    // e = 4
)

// 枚D的常量都为同一cd? 可以使用单序列格?
const (
    a = iota    // a int32 = 0
    b            // b int32 = 1
    c            // c int32 = 2
)

// 枚D序列中的未指定类型的帔R会跟随序列前面最后一ơ出现类型定义的cd
const (
    a byte = iota    // a uint8 = 0
    b                // b uint8 = 1
    c                // c uint8 = 2
    d rune = iota    // d int32 = 3
    e                // e int32 = 4
    f                // f int32 = 5
)

// iota自增值只在一个常量定义组合中有效,跛_帔Rl合定义后iota值归0
const (
    a = iota    // a int32 = 0
    b            // b int32 = 1
    c            // c int32 = 2
)
const (
    e = iota    // e int32 = 0    (iota重新初始化ƈ自增)
    f            // f int32 = 1
)

// 定制iota序列初始g步进?nbsp;(通过数学公式实现)
const (
    a = (iota + 2) * 3    // a int32 = 0    (a=(0+2)*3) 初始gؓ6,步进gؓ3
    b                    // b int32 = 3    (b=(1+2)*3)
    c                    // c int32 = 6    (c=(2+2)*3)
    d                    // d int32 = 9    (d=(3+2)*3)
)

// 数组声明带有长度信息Q数l的长度固定
var a [3]int = [3]int{0, 1, 2}    // a = [0 1 2]
var b [3]int = [3]int{}    // b = [0 0 0]
var c = [3]int{}    // c = [0 0 0]
d := [3]int{}    // d = [0 0 0]
fmt.Printf("%T\t%#v\t%d\t%d\n", d, d, len(d), cap(d))    // [3]int    [3]int{0, 0, 0}    3    3
// 使用自动计算数组初始数据的长?/span>
var a = []int{0, 1, 2}
x := [][3]int{{0, 1, 2}, {3, 4, 5}}

// slice 指向数组的|q且同时包含了长度信?/span>
var a []int
fmt.Printf("%T\t%#v\t%d\t%d\n", a, a, len(a), cap(a))    // []int    []int(nil)    0    0
var a = new([]int)
fmt.Printf("%T\t%#v\t%d\t%d\n", a, a, len(*a), cap(*a))    // *[]int    &[]int(nil)    0    0
var b = make([]int, 0)
fmt.Printf("%T\t%#v\t%d\t%d\n", b, b, len(b), cap(b))    // []int    []int{}    0    0
var c = make([]int, 3, 10)
fmt.Printf("%T\t%#v\t%d\t%d\n", c, c, len(c), cap(c))    // []int    []int{}    3    10
var d []int = []int{0, 1, 2}
fmt.Printf("%T\t%#v\t%d\t%d\n", d, d, len(d), cap(d))    // []int    []int{0, 1, 2}    3    3

// slice 可以重新切片Q创Z个新?nbsp;slice 值指向相同的数组
s := []int{0, 1, 2, 3, 4}
fmt.Println(s[1,3])    // [1 2]    (截取从开始烦引到l束索引-1 之间的片D?
fmt.Println(s[:4])    // [0 1 2 3]
fmt.Println(s[1:])    // [1 2 3 4]
fmt.Println(s[1:1])    // []

// 向slice中添加元?/span>
s := make([]string, 3)
s = append(s, "a")


// map 在用之前必ȝ make 来创建(不是 newQ;一个gؓ nil ?nbsp;map 是空的,q且不能赋?/span>
var m map[int]int
m[0] = 0    // × runtime error: assignment to entry in nil map
fmt.Printf("type: %T\n", m)    // map[int]int
fmt.Printf("value: %#v\n", m)    // map[int]int(nil)
fmt.Printf("value: %v\n", m)    // map[]
fmt.Println("is nil: ", nil == m)    // true
fmt.Println("length: ", len(m))    // 0Qif m is nil, len(m) is zero.

var m map[int]int = make(map[int]int)
m[0] = 0    // 插入或修改元?/span>
fmt.Printf("type: %T\n", m)        // map[int]int
fmt.Printf("value: %#v\n", m)        // map[int]int(0:0)
fmt.Printf("value: %v\n", m)        // map[0:0]
fmt.Println("is nil: ", nil == m)    // false
fmt.Println("length: ", len(m))        // 1

m = map[int]int{
0:0,
1:1,    // 最后的逗号是必ȝ
}
m = map[string]S{
"a":S{0,1},
"b":{2,3},    // cd名称可省?/span>
}
a := m["a"]    // 取?/span>
a, ok := m["a"]    // 取? q过ok(bool)判断key对应的元素是否存?
delete(m, "a")    // 删除key对应的元?

// l构体(structQ就是一个字D늚集合Q?nbsp;type 定义跟其字面意思相W?/span>
type S struct {
    A int
    B, c string
}
type (
    A struct {
        s *S
    }
    B struct {
        A    // l合
    }
)
// l构体文法表C通过l构体字D늚g为列表来新分配一个结构体?/span>
var s S = S{0, "1", "2"}
// 使用 Name: 语法可以仅列出部分字Dc(字段名的序无关。)
var s S = S{A: 0, B: "1"}
var s S = S{}
// Ҏ的前~ & 构造了指向l构体文法的指针?/span>
var s *S = &S{0, "1", "2"}

// 表达?nbsp;new(T) 分配了一个零初始化的 T |q返回指向它的指?/span>
var s *S = new(S)
// 有指针,但是没有指针q算Q结构体字段使用点号来访?br />// l构体字D可以通过l构体指针来讉K。通过指针间接的访问是透明?/span>
fmt.Println(s.A)
fmt.Println((*s).A)

// TODO interface
type IF interface {
    a()
}

// TODO chanel

// TODO error

// if 语句 括?nbsp;( )是可选的Q?nbsp;{ } 是必ȝ?/span>
if (i < 0)        // ~译错误.
    println(i)

if i < 0        // ~译错误.
    println(i)

if (i < 0) {    // ~译通过.
    println(i)
}
if i < 0 {
    println(i)
else {
    println(i)
}

// 可以在条件之前执行一个简单的语句Q由q个语句定义的变量的作用域仅?nbsp;if/else 范围之内
if (i := 0; i < 1) {    // ~译错误.
    println(i)
}

if i := 0; (i < 1) {    // ~译通过.
    println(i)
}

if i := 0; i < 0 {    // 使用gofmt格式化代码会自动U除代码中不必要的小括号( )
    println(i)
else if i == 0 {
    println(i)
else {
    println(i)
}

// if语句作用域范围内定义的变量会覆盖外部同名变量,(与方法函数内局部变量覆盖全局变量相同)
a, b := 0, 1
if a, b := 3, 4; a > 1 && b > 2 {
    println(a, b)    // 3 4
}
println(a, b)    // 0 1


// 只有一U@环结构,for 循环。可以让前置、后|语句ؓI,或者全为空
for i := 0; i < 10; i++ {}
for i := 0; i < 10; {}
for ; i < 10; i++ {}
for ; i < 10; {}
for i < 10 {}
for ; ; {}
for {}

// 括?nbsp;( )是可选的Q?nbsp;{ } 是必ȝ?/span>
for (i := 0; i < 10; i++) {}    // ~译错误.
for i := 0; (i < 10); i++ {}    // ~译通过.
for (i < 10) {}    // ~译通过.

// TODO continue

// TODO for range

// TODO switch
// TODO fallthrough break
// TODO type assertion

// TODO select

// TODO goto

// 函数可以没有参数或接受多个参?/span>
func f() {}
func f(a int) {}
func f(a int, b byte) {}
func f(a int) {}    // 可变参数
func f(a int, b bool, c string) {}
// 函数可以q回L数量的返回?/span>
func f() int {
    return 0
}
func f() intstring {
    return 0, "A"
}
// 函数q回l果参数Q可以像变量那样命名和?/span>
func f() a int, b string {
    a = 1
    b = "B"
    return    // 或?nbsp;return a, b
}

// 当两个或多个q箋的函数命名参数是同一cdQ则除了最后一个类型之外,其他都可以省?/span>
func f(a,b,c int) {}
func f() a,b,c int {}
func f(a,b,c int) x,y,z int {}

// 函数也是|可以函数赋值给变量
var f (func(i intint) = func(i intint {
    return i
}
fmt.Println(f(3))    // 3
var f func() int = func() int {
    return 0
}
fmt.Println(f())    // 0
var f func() = func() {}
var f = func() {}
f := func() {}

// TODO defer

// TODO Ҏ

// TODO 内徏函数
append 
cap 
close 
complex 
copy 
delete 
imag 
len 
make 
new 
panic 
print 
println 
real 
recover

// TODO q发
go func() {}


oathleo 2013-08-02 16:15 发表评论
]]>
Go语言文g操作http://www.aygfsteel.com/oathleo/archive/2013/08/02/402287.htmloathleooathleoFri, 02 Aug 2013 02:43:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402287.htmlhttp://www.aygfsteel.com/oathleo/comments/402287.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402287.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/402287.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/402287.html写程序离不了文g操作Q?/span>q里ȝ?/span>go语言文g操作?/span>

一、徏立与打开

建立文g函数Q?/p>

func Create(name string) (file *File, err Error)

func NewFile(fd int, name string) *File

具体见官|:http://golang.org/pkg/os/#Create

 

打开文g函数Q?/p>

func Open(name string) (file *File, err Error)

func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

具体见官|:http://golang.org/pkg/os/#Open

 

二、写文g

写文件函敎ͼ

func (file *File) Write(b []byte) (n int, err Error)

func (file *File) WriteAt(b []byte, off int64) (n int, err Error)

func (file *File) WriteString(s string) (ret int, err Error)

具体见官|:http://golang.org/pkg/os/#File.Write 

写文件示例代码:

package main import (         "os"         "fmt" ) func main() {         userFile := "test.txt"         fout,err := os.Create(userFile)         defer fout.Close()         if err != nil {                 fmt.Println(userFile,err)                 return         }         for i:= 0;i<10;i++ {                 fout.WriteString("Just a test!\r\n")                 fout.Write([]byte("Just a test!\r\n"))         } }

三、读文g

L件函敎ͼ

func (file *File) Read(b []byte) (n int, err Error)

func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

具体见官|:http://golang.org/pkg/os/#File.Read

L件示例代码:

package main import (         "os"         "fmt" ) func main() {         userFile := "test.txt"         fin,err := os.Open(userFile)         defer fin.Close()         if err != nil {                 fmt.Println(userFile,err)                 return         }         buf := make([]byte, 1024)         for{                 n, _ := fin.Read(buf)                 if 0 == n { break }                 os.Stdout.Write(buf[:n])         } }

四、删除文?/span>

函数Q?/span>

func Remove(name string) Error



oathleo 2013-08-02 10:43 发表评论
]]>
goLang dInthttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402283.htmloathleooathleoFri, 02 Aug 2013 02:13:00 GMThttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402283.htmlhttp://www.aygfsteel.com/oathleo/comments/402283.htmlhttp://www.aygfsteel.com/oathleo/archive/2013/08/02/402283.html#Feedback0http://www.aygfsteel.com/oathleo/comments/commentRss/402283.htmlhttp://www.aygfsteel.com/oathleo/services/trackbacks/402283.html
func readInt32(conn net.Conn) int32 {
    num_byte := make([]byte, 4)
    conn.Read(num_byte)
    var value int32 = 0
//    //windows
//    byte2 := num_byte[2]
//    byte3 := num_byte[3]
//    num_byte[3] = num_byte[0]
//    num_byte[0] = byte3
//    num_byte[2] = num_byte[1]
//    num_byte[1] = byte2
//    //windows

    
//windows
    num_byte[0],num_byte[1],num_byte[2],num_byte[3] = num_byte[3],num_byte[2],num_byte[1],num_byte[0]

    for i := 0; i < 4; i++ {
        shift := uint32((4 - 1 - i) * 8)
        value = value + (int32(num_byte[i])&0x000000FF)<<shift
    }
    return value
}


oathleo 2013-08-02 10:13 发表评论
]]>
վ֩ģ壺 | | | ʮ| ȷ| | ɽ| | | | | | | ƽ| | ۶| | | | | | Ž| ǧ| | | | | ɰ| | | | | | | Ϸ| | Ȩ| | ֶ| | пѷ|