咖啡伴侣

呆在上海
posts - 163, comments - 156, trackbacks - 0, articles - 2

数组 Arrays

数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。在初始化后长度是固定的,无法修改其长度。当作为方法的入参传入时将复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度。

初始化

数组的初始化有多种形式,查看示例代码 , 在线运行示例代码

  • [5] int {1,2,3,4,5} 
    长度为5的数组,其元素值依次为:1,2,3,4,5
  • [5] int {1,2} 
    长度为5的数组,其元素值依次为:1,2,0,0,0 。在初始化时没有指定初值的元素将会赋值为其元素类型int的默认值0,string的默认值是""
  • [...] int {1,2,3,4,5} 
    长度为5的数组,其长度是根据初始化时指定的元素个数决定的
  • [5] int { 2:1,3:2,4:3} 
    长度为5的数组,key:value,其元素值依次为:0,0,1,2,3。在初始化时指定了2,3,4索引中对应的值:1,2,3
  • [...] int {2:1,4:3} 
    长度为5的数组,起元素值依次为:0,0,1,0,3。由于指定了最大索引4对应的值3,根据初始化的元素个数确定其长度为5

赋值与使用

数组通过下标访问元素,可修改其元素值

arr :=[...] int {1,2,3,4,5} arr[4]=arr[1]+len(arr)      //arr[4]=2+5 

通过for遍历数组元素,查看示例代码,在线运行示例代码

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

数组是值类型,将一个数组赋值给另一个数组时将复制一份新的元素,查看示例代码,在线运行示例代码

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 

切片 Slices

数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型Slices切片,与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。切片中有两个概念:一是len长度,二是cap容量,长度是指已经被赋过值的最大下标+1,可通过内置函数len()获得。容量是指切片目前可容纳的最多元素个数,可通过内置函数cap()获得。切片是引用类型,因此在当传递切片时将引用同一指针,修改值将会影响其他的对象。

初始化

切片可以通过数组来初始化,也可以通过内置函数make()初始化 .初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容 查看示例代码在线运行示例代码

  • s :=[] int {1,2,3 } 
    直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3
  • s := arr[:] 
    初始化切片s,是数组arr的引用
  • s := arr[startIndex:endIndex] 
    将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
  • s := arr[startIndex:] 
    缺省endIndex时将表示一直到arr的最后一个元素
  • s := arr[:endIndex] 
    缺省startIndex时将表示从arr的第一个元素开始
  • s1 := s[startIndex:endIndex] 
    通过切片s初始化切片s1
  • s :=make([]int,len,cap) 
    通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片

赋值与使用

切片是引用类型,在使用时需要注意其操作。查看示例代码 ,在线运行示例代码 切片可以通过内置函数append(slice []Type,elems ...Type)追加元素,elems可以是一排type类型的数据,也可以是slice,因为追加的一个一个的元素,因此如果将一个slice追加到另一个slice中需要带上"...",这样才能表示是将slice中的元素依次追加到另一个slice中。另外在通过下标访问元素时下标不能超过len大小,如同数组的下标不能超出len范围一样。

  • s :=append(s,1,2,3,4)
  • s :=append(s,s1...)
转载时请注明出处!老虞http://www.cnblogs.com/howDo/

posted @ 2013-09-12 09:20 oathleo 阅读(1800) | 评论 (0)编辑 收藏

服务器端/客户端 在 login的时候经常多次read write
这个时候 read 要完整,第一次没有read完,就write,第二次read 到的仍然是上次没有read完的数据

posted @ 2013-09-11 08:56 oathleo 阅读(285) | 评论 (0)编辑 收藏

// bufio 包实现了带缓存的 I/O 操作
// 它封装一个 io.Reader 或 io.Writer 对象
// 使其具有缓存和一些文本读写功能
------------------------------------------------------------
// bufio.go
------------------------------------------------------------
// Reader 实现了带缓存的 io.Reader 对象
type Reader struct {
// 私有字段
}
// NewReaderSize 将 rd 封装成一个拥有 size 大小缓存的 bufio.Reader 对象
// 如果 rd 的基类型就是 bufio.Reader 类型,而且拥有足够的缓存
// 则直接将 rd 转换为基类型并返回
func NewReaderSize(rd io.Reader, size int) *Reader
// NewReader 相当于 NewReaderSize(rd, 4096)
func NewReader(rd io.Reader) *Reader
------------------------------------------------------------
// Peek 返回缓存的一个切片,该切片引用缓存中前 n 字节数据
// 该操作不会将数据读出,只是引用
// 引用的数据在下一次读取操作之前是有效的
// 如果引用的数据长度小于 n,则返回一个错误信息
// 如果 n 大于缓存的总大小,则返回 ErrBufferFull
// 通过 Peek 的返回值,可以修改缓存中的数据
// 但是不能修改底层 io.Reader 中的数据
func (b *Reader) Peek(n int) ([]byte, error)
func main() {
s := strings.NewReader("ABCDEFG")
br := bufio.NewReader(s)
b, _ := br.Peek(5)
fmt.Printf("%s\n", b)
// ABCDE
b[0] = 'a'
b, _ = br.Peek(5)
fmt.Printf("%s\n", b)
// aBCDE
}
------------------------------------------------------------
// Read 从 b 中读出数据到 p 中,返回读出的字节数
// 如果 p 的大小 >= 缓存的总大小,而且缓存不为空
// 则只能读出缓存中的数据,不会从底层 io.Reader 中提取数据
// 如果 p 的大小 >= 缓存的总大小,而且缓存为空
// 则直接从底层 io.Reader 向 p 中读出数据,不经过缓存
// 只有当 b 中无可读数据时,才返回 (0, io.EOF)
func (b *Reader) Read(p []byte) (n int, err error)
func main() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
b := make([]byte, 20)
n, err := br.Read(b)
fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)
// ABCDEFGHIJKLMNOPQRST 20 <nil>
n, err = br.Read(b)
fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)
// UVWXYZ1234567890     16 <nil> 
n, err = br.Read(b)
fmt.Printf("%-20s %-2v %v\n", b[:n], n, err)
//                      0  EOF
}
------------------------------------------------------------
// ReadByte 从 b 中读出一个字节并返回
// 如果 b 中无可读数据,则返回一个错误
func (b *Reader) ReadByte() (c byte, err error)
// UnreadByte 撤消最后一次读出的字节
// 只有最后读出的字节可以被撤消
// 无论任何操作,只要有内容被读出,就可以用 UnreadByte 撤消一个字节
func (b *Reader) UnreadByte() error
func main() {
s := strings.NewReader("ABCDEFG")
br := bufio.NewReader(s)
c, _ := br.ReadByte()
fmt.Printf("%c\n", c)
// A
c, _ = br.ReadByte()
fmt.Printf("%c\n", c)
// B
br.UnreadByte()
c, _ = br.ReadByte()
fmt.Printf("%c\n", c)
// B
}
------------------------------------------------------------
// ReadRune 从 b 中读出一个 UTF8 编码的字符并返回
// 同时返回该字符的 UTF8 编码长度
// 如果 UTF8 序列无法解码出一个正确的 Unicode 字符
// 则只读出 b 中的一个字节,并返回 U+FFFD 字符,size 返回 1
func (b *Reader) ReadRune() (r rune, size int, err error)
// UnreadRune 撤消最后一次读出的 Unicode 字符
// 如果最后一次执行的不是 ReadRune 操作,则返回一个错误
// 因此,UnreadRune 比 UnreadByte 更严格
func (b *Reader) UnreadRune() error
func main() {
s := strings.NewReader("你好,世界!")
br := bufio.NewReader(s)
c, size, _ := br.ReadRune()
fmt.Printf("%c %v\n", c, size)
// 你 3
c, size, _ = br.ReadRune()
fmt.Printf("%c %v\n", c, size)
// 好 3
br.UnreadRune()
c, size, _ = br.ReadRune()
fmt.Printf("%c %v\n", c, size)
// 好 3
}
------------------------------------------------------------
// Buffered 返回缓存中数据的长度
func (b *Reader) Buffered() int
func main() {
s := strings.NewReader("你好,世界!")
br := bufio.NewReader(s)
fmt.Println(br.Buffered())
// 0
br.Peek(1)
fmt.Println(br.Buffered())
// 18
}
------------------------------------------------------------
// ReadSlice 在 b 中查找 delim 并返回 delim 及其之前的所有数据的切片
// 该操作会读出数据,返回的切片是已读出数据的引用
// 切片中的数据在下一次读取操作之前是有效的
//
// 如果 ReadSlice 在找到 delim 之前遇到错误
// 则读出缓存中的所有数据并返回,同时返回遇到的错误(通常是 io.EOF)
// 如果在整个缓存中都找不到 delim,则 err 返回 ErrBufferFull
// 如果 ReadSlice 能找到 delim,则 err 始终返回 nil
//
// 因为返回的切片中的数据有可能被下一次读写操作修改
// 因此大多数操作应该使用 ReadBytes 或 ReadString,它们返回的不是数据引用
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
func main() {
s := strings.NewReader("ABC DEF GHI JKL")
br := bufio.NewReader(s)
w, _ := br.ReadSlice(' ')
fmt.Printf("%q\n", w)
// "ABC "
w, _ = br.ReadSlice(' ')
fmt.Printf("%q\n", w)
// "DEF "
w, _ = br.ReadSlice(' ')
fmt.Printf("%q\n", w)
// "GHI "
}
------------------------------------------------------------
// ReadLine 是一个低级的原始的行读取操作
// 大多数情况下,应该使用 ReadBytes('\n') 或 ReadString('\n')
// 或者使用一个 Scanner
//
// ReadLine 通过调用 ReadSlice 方法实现,返回的也是缓存的切片
// ReadLine 尝试返回一个单行数据,不包括行尾标记(\n 或 \r\n)
// 如果在缓存中找不到行尾标记,则设置 isPrefix 为 true,表示查找未完成
// 同时读出缓存中的数据并作为切片返回
// 只有在当前缓存中找到行尾标记,才将 isPrefix 设置为 false,表示查找完成
// 可以多次调用 ReadLine 来读出一行
// 返回的数据在下一次读取操作之前是有效的
// 如果 ReadLine 无法获取任何数据,则返回一个错误信息(通常是 io.EOF)
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
func main() {
s := strings.NewReader("ABC\nDEF\r\nGHI\r\nJKL")
br := bufio.NewReader(s)
w, isPrefix, _ := br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix)
// "ABC" false
w, isPrefix, _ = br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix)
// "DEF" false
w, isPrefix, _ = br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix)
// "GHI" false
}
------------------------------------------------------------
// ReadBytes 在 b 中查找 delim 并读出 delim 及其之前的所有数据
// 如果 ReadBytes 在找到 delim 之前遇到错误
// 则返回遇到错误之前的所有数据,同时返回遇到的错误(通常是 io.EOF)
// 只有当 ReadBytes 找不到 delim 时,err 才不为 nil
// 对于简单的用途,使用 Scanner 可能更方便
func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
func main() {
s := strings.NewReader("ABC DEF GHI JKL")
br := bufio.NewReader(s)
w, _ := br.ReadBytes(' ')
fmt.Printf("%q\n", w)
// "ABC "
w, _ = br.ReadBytes(' ')
fmt.Printf("%q\n", w)
// "DEF "
w, _ = br.ReadBytes(' ')
fmt.Printf("%q\n", w)
// "GHI "
}
------------------------------------------------------------
// ReadString 功能同 ReadBytes,只不过返回的是一个字符串
func (b *Reader) ReadString(delim byte) (line string, err error)
func main() {
s := strings.NewReader("ABC DEF GHI JKL")
br := bufio.NewReader(s)
w, _ := br.ReadString(' ')
fmt.Printf("%q\n", w)
// "ABC "
w, _ = br.ReadString(' ')
fmt.Printf("%q\n", w)
// "DEF "
w, _ = br.ReadString(' ')
fmt.Printf("%q\n", w)
// "GHI "
}
------------------------------------------------------------
// WriteTo 实现了 io.WriterTo 接口
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
func main() {
s := strings.NewReader("ABCEFG")
br := bufio.NewReader(s)
b := bytes.NewBuffer(make([]byte, 0))
br.WriteTo(b)
fmt.Printf("%s\n", b)
// ABCEFG
}
------------------------------------------------------------
// Writer 实现了带缓存的 io.Writer 对象
// 如果在向 Writer 中写入数据的过程中遇到错误
// 则 Writer 不会再接受任何数据
// 而且后续的写入操作都将返回错误信息
type Writer struct {
// 私有字段
}
// NewWriterSize 将 wr 封装成一个拥有 size 大小缓存的 bufio.Writer 对象
// 如果 wr 的基类型就是 bufio.Writer 类型,而且拥有足够的缓存
// 则直接将 wr 转换为基类型并返回
func NewWriterSize(wr io.Writer, size int) *Writer
// NewWriter 相当于 NewWriterSize(wr, 4096)
func NewWriter(wr io.Writer) *Writer
------------------------------------------------------------
// Flush 将缓存中的数据提交到底层的 io.Writer 中
func (b *Writer) Flush() error
// Available 返回缓存中的可以空间
func (b *Writer) Available() int
// Buffered 返回缓存中未提交的数据长度
func (b *Writer) Buffered() int
// Write 将 p 中的数据写入 b 中,返回写入的字节数
// 如果写入的字节数小于 p 的长度,则返回一个错误信息
func (b *Writer) Write(p []byte) (nn int, err error)
// WriteString 同 Write,只不过写入的是字符串
func (b *Writer) WriteString(s string) (int, error)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
fmt.Println(bw.Available()) // 4096
fmt.Println(bw.Buffered())  // 0
bw.WriteString("ABCDEFGH")
fmt.Println(bw.Available()) // 4088
fmt.Println(bw.Buffered())  // 8
fmt.Printf("%q\n", b)       // ""
bw.Flush()
fmt.Println(bw.Available()) // 4096
fmt.Println(bw.Buffered())  // 0
fmt.Printf("%q\n", b)       // "ABCEFG"
}
------------------------------------------------------------
// WriteByte 向 b 中写入一个字节
func (b *Writer) WriteByte(c byte) error
// WriteRune 向 b 中写入 r 的 UTF8 编码
// 返回 r 的编码长度
func (b *Writer) WriteRune(r rune) (size int, err error)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
bw.WriteByte('H')
bw.WriteByte('e')
bw.WriteByte('l')
bw.WriteByte('l')
bw.WriteByte('o')
bw.WriteByte(' ')
bw.WriteRune('世')
bw.WriteRune('界')
bw.WriteRune('!')
bw.Flush()
fmt.Println(b) // Hello 世界!
}
------------------------------------------------------------
// ReadFrom 实现了 io.ReaderFrom 接口
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
s := strings.NewReader("Hello 世界!")
bw := bufio.NewWriter(b)
bw.ReadFrom(s)
bw.Flush()
fmt.Println(b) // Hello 世界!
}
------------------------------------------------------------
// ReadWriter 集成了 bufio.Reader 和 bufio.Writer
// 它实现了 io.ReadWriter 接口
type ReadWriter struct {
*Reader
*Writer
}
// NewReadWriter 封装 r 和 w 为一个 bufio.ReadWriter 对象
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
------------------------------------------------------------
// scan.go
------------------------------------------------------------
// Scanner 提供了一个方便的接口来读取数据,例如读取一个多行文本
// 连续调用 Scan 方法将扫描数据中的“指定部分”,跳过各个“指定部分”之间的数据
// Scanner 使用了缓存,所以“指定部分”的长度不能超出缓存的长度
// Scanner 需要一个 SplitFunc 类型的“切分函数”来确定“指定部分”的格式
// 本包中提供的“切分函数”有“行切分函数”、“字节切分函数”、“UTF8字符编码切分函数”
// 和“单词切分函数”,用户也可以自定义“切分函数”
// 默认的“切分函数”为“行切分函数”,用于获取数据中的一行数据(不包括行尾符)
//
// 扫描在遇到下面的情况时会停止:
// 1、数据扫描完毕,遇到 io.EOF
// 2、遇到读写错误
// 3、“指定部分”的长度超过了缓存的长度
// 如果要对数据进行更多的控制,比如的错误处理或扫描更大的“指定部分”或顺序扫描
// 则应该使用 bufio.Reader
type Scanner struct {
// 私有字段
}
// SplitFunc 用来定义“切分函数”类型
// data 是要扫描的数据
// atEOF 标记底层 io.Reader 中的数据是否已经读完
// advance 返回 data 中已处理的数据长度
// token 返回找到的“指定部分”
// err 返回错误信息
// 如果在 data 中无法找到一个完整的“指定部分”
// 则 SplitFunc 返回 (0, nil) 来告诉 Scanner
// 向缓存中填充更多数据,然后再次扫描
//
// 如果返回的 err 是非 nil 值,扫描将被终止,并返回错误信息
//
// 如果 data 为空,则“切分函数”将不被调用
// 意思是在 SplitFunc 中不必考虑 data 为空的情况
//
// SplitFunc 的作用很简单,从 data 中找出你感兴趣的数据,然后返回
// 并告诉调用者,data 中有多少数据你已经处理过了
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
// NewScanner 创建一个 Scanner 来扫描 r
// 默认切分函数为 ScanLines
func NewScanner(r io.Reader) *Scanner
// Err 返回扫描过程中遇到的非 EOF 错误
// 供用户调用,以便获取错误信息
func (s *Scanner) Err() error
------------------------------------------------------------
// Bytes 将最后一次扫描出的“指定部分”作为一个切片返回(引用传递)
// 下一次的 Scan 操作会覆盖本次返回的结果
func (s *Scanner) Bytes() []byte
// Text 将最后一次扫描出的“指定部分”作为字符串返回(值传递)
func (s *Scanner) Text() string
------------------------------------------------------------
// Scan 在 Scanner 的数据中扫描“指定部分”
// 找到后,用户可以通过 Bytes 或 Text 方法来取出“指定部分”
// 如果扫描过程中遇到错误,则终止扫描,并返回 false
func (s *Scanner) Scan() bool
func main() {
s := strings.NewReader("ABC\nDEF\r\nGHI\nJKL")
bs := bufio.NewScanner(s)
for bs.Scan() {
fmt.Printf("%s %v\n", bs.Bytes(), bs.Text())
}
// ABC ABC
// DEF DEF
// GHI GHI
// JKL JKL
}
------------------------------------------------------------
// Split 用于设置 Scanner 的“切分函数”
// 这个函数必须在调用 Scan 前执行
func (s *Scanner) Split(split SplitFunc)
func main() {
s := strings.NewReader("ABC DEF GHI JKL")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanWords)
for bs.Scan() {
fmt.Println(bs.Text())
}
// ABC
// DEF
// GHI
// JKL
}
------------------------------------------------------------
// ScanBytes 是一个“切分函数”
// 用来找出 data 中的单个字节并返回
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
func main() {
s := strings.NewReader("Hello 世界!")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanBytes)
for bs.Scan() {
fmt.Printf("%s ", bs.Text())
}
}
------------------------------------------------------------
// ScanRunes 是一个“切分函数”
// 用来找出 data 中的单个 UTF8 字符的编码并返回
// 如果 UTF8 解码出错,则返回的 U+FFFD 会被做为 "\xef\xbf\xbd" 返回
// 这使得用户无法区分“真正的U+FFFD字符”和“解码错误的返回值”
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
func main() {
s := strings.NewReader("Hello 世界!")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanRunes)
for bs.Scan() {
fmt.Printf("%s ", bs.Text())
} // H e l l o   世 界 !
}
------------------------------------------------------------
// ScanLines 是一个“切分函数”
// 用来找出 data 中的单行数据并返回(包括空行)
// 行尾标记可能是 \n 或 \r\n(返回值不包括行尾标记)
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
------------------------------------------------------------
// ScanWords 是一个“切分函数”
// 用来找出 data 中的单词
// 单词以空白字符分隔,空白字符由 unicode.IsSpace 定义
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

posted @ 2013-09-05 16:01 oathleo 阅读(1193) | 评论 (0)编辑 收藏

     摘要: 周末天气不好,只能宅在家里,于是就顺便看了一下Go语言,觉得比较有意思,所以写篇文章介绍一下。我想写一篇你可以在乘坐地铁或公交车上下班时就可以初步了解一门语言的文章。所以,下面的文章主要是以代码和注释为主。只需要你对C语言,Unix,Python有一点基础,我相信你会在30分钟左右读完并对Go语言有一些初步了解的。Hello World文件名 hello.go1234567package main...  阅读全文

posted @ 2013-09-03 09:20 oathleo 阅读(231) | 评论 (0)编辑 收藏

     摘要: 希望你看到这篇文章的时候还是在公交车和地铁上正在上下班的时间,我希望我的这篇文章可以让你利用这段时间了解一门语言。当然,希望你不会因为看我的文章而错过站。呵呵。如果你还不了解Go语言的语法,还请你移步先看一下上篇——《Go语言简介(上):语法》goroutineGoRoutine主要是使用go关键字来调用函数,你还可以使用匿名函数,如下所示:1234567891011121...  阅读全文

posted @ 2013-09-03 09:20 oathleo 阅读(675) | 评论 (0)编辑 收藏

分类: Go2013-07-31 11:02 177人阅读 评论(0) 收藏 举报
1、整形到字符串:
    
  1. var i int = 1  
  2. var s string  
  1. s = strconv.Itoa(i) 或者 s = FormatInt(int64(i), 10)  

2、字符串到整形
    
  1. var s string = "1"  
  2. var i int  
  3. i, err = strconv.Atoi(s) 或者 i, err = ParseInt(s, 10, 0)  

3、字符串到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到整形
    直接使用float(i) 或者 int(f) 直接进行转换即可

posted @ 2013-08-30 11:37 oathleo 阅读(24342) | 评论 (0)编辑 收藏

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)

输出:10.01

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

输出:10.10


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

-1 代表输出的精度小数点后的位数,如果是<0的值,则返回最少的位数来表示该数,如果是大于0的则返回对应位数的值

64 为float的类型,go中float分为32和64位,因此就需要传入32或者64


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


golang strconv.ParseInt 是将字符串转换为数字的函数,功能灰常之强大,看的我口水直流.

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

参数1 数字的字符串形式

参数2 数字字符串的进制 比如二进制 八进制 十进制 十六进制

参数3 返回结果的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}


posted @ 2013-08-30 11:26 oathleo 阅读(5737) | 评论 (0)编辑 收藏

做了下go和java的http性能的简单比较
服务端直接输出字符串
使用JMeter
windows下
 



2000的并发,测试结果很出乎意料,go不会这么差吧


研究了半小时,原因如下
tomcat的servlet里加了        response.setHeader("Pragma""no-cache");
go里没有设置该参数

设置后重新跑测试



可以了吧




posted @ 2013-08-27 15:29 oathleo 阅读(7020) | 评论 (5)编辑 收藏

golang html 与 golang客户端 上传文件

 May 30 , 2013 at 08:30 am -  263点击 -  0 评论

小文件上传

 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"//这里的file很重要,必须和服务器端的FormFile一致

    
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上传,原文

package main

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

// 获取大小的接口
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, 
"上传文件的大小为: %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)
    }
}



大文件上传

关键的不同是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) 
}



posted @ 2013-08-27 09:10 oathleo 阅读(3036) | 评论 (0)编辑 收藏

        rune_str := []rune(info)
        fmt.Print("rune_len:" , len(rune_str))
        fmt.Print("string_len:" , len(info))

string 和对应的 rune数组的len不一定相同

如果info是有中文的,则两个length是不一样的,做string处理的时候,要注意

posted @ 2013-08-19 11:31 oathleo 阅读(2750) | 评论 (0)编辑 收藏

仅列出标题
共17页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last