咖啡伴侶

          呆在上海
          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 閱讀(1804) | 評論 (0)編輯 收藏

          服務器端/客戶端 在 login的時候經常多次read write
          這個時候 read 要完整,第一次沒有read完,就write,第二次read 到的仍然是上次沒有read完的數據

          posted @ 2013-09-11 08:56 oathleo 閱讀(290) | 評論 (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 閱讀(1199) | 評論 (0)編輯 收藏

               摘要: 周末天氣不好,只能宅在家里,于是就順便看了一下Go語言,覺得比較有意思,所以寫篇文章介紹一下。我想寫一篇你可以在乘坐地鐵或公交車上下班時就可以初步了解一門語言的文章。所以,下面的文章主要是以代碼和注釋為主。只需要你對C語言,Unix,Python有一點基礎,我相信你會在30分鐘左右讀完并對Go語言有一些初步了解的。Hello World文件名 hello.go1234567package main...  閱讀全文

          posted @ 2013-09-03 09:20 oathleo 閱讀(232) | 評論 (0)編輯 收藏

               摘要: 希望你看到這篇文章的時候還是在公交車和地鐵上正在上下班的時間,我希望我的這篇文章可以讓你利用這段時間了解一門語言。當然,希望你不會因為看我的文章而錯過站。呵呵。如果你還不了解Go語言的語法,還請你移步先看一下上篇——《Go語言簡介(上):語法》goroutineGoRoutine主要是使用go關鍵字來調用函數,你還可以使用匿名函數,如下所示:1234567891011121...  閱讀全文

          posted @ 2013-09-03 09:20 oathleo 閱讀(678) | 評論 (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 閱讀(24347) | 評論 (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 閱讀(5741) | 評論 (0)編輯 收藏

          做了下go和java的http性能的簡單比較
          服務端直接輸出字符串
          使用JMeter
          windows下
           



          2000的并發,測試結果很出乎意料,go不會這么差吧


          研究了半小時,原因如下
          tomcat的servlet里加了        response.setHeader("Pragma""no-cache");
          go里沒有設置該參數

          設置后重新跑測試



          可以了吧




          posted @ 2013-08-27 15:29 oathleo 閱讀(7042) | 評論 (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 閱讀(3044) | 評論 (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 閱讀(2757) | 評論 (0)編輯 收藏

          僅列出標題
          共17頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 Last 
          主站蜘蛛池模板: 田阳县| 图木舒克市| 西乌珠穆沁旗| 万年县| 绥江县| 博野县| 和林格尔县| 崇左市| 仪陇县| 防城港市| 房山区| 综艺| 聂荣县| 冷水江市| 高阳县| 噶尔县| 曲阜市| 天峻县| 肥东县| 钦州市| 巍山| 寿阳县| 赣州市| 武冈市| 赞皇县| 唐河县| 西平县| 田东县| 京山县| 石渠县| 秦安县| 辽源市| 灌云县| 万年县| 增城市| 南安市| 南靖县| 寻甸| 商水县| 林西县| 哈密市|