golang 筆記

emacs 開發環境

spacemacs已經集成了很多功能,可是缺乏代碼提示。所以還須要gocode來輔助。git

  1. 安裝所需的命令 github

    go get -u -v github.com/nsf/gocode
    go get -u -v github.com/rogpeppe/godef go get -u -v
    golang.org/x/tools/cmd/guru go get -u -v
    golang.org/x/tools/cmd/gorename go get -u -v
    golang.org/x/tools/cmd/goimportsgolang

  2. 配置文件 數組

    將gocode中的go-autocomplete.el拷貝至elpa/go-mode
    向space macs手動添加包:dotspacemacs-additional-packages '(go-autocomplete)
    dotspacemace/user-config中添加如下內容緩存

    (require 'go-autocomplete)
    (require 'auto-complete-config)
    (ac-config-default)

GO

package 手冊go語言聖經安全

語法

  1. 聲明 :var|const|type|func name (類型) (值)數據結構

    var 顯式聲明一個變元。var name Type
    := 語法能夠隱式地聲明一個變元。name := f() | a
    隱式聲明的變元的做用域是能夠被覆蓋的,但顯式的不能。app

    var a int //1.會致使3出錯
    a := 1    //2.不會致使3處出錯
    {
    a:= 2     //3.
    }

    const a=2, const a float64=2 函數

    type name definedefine= Type | struct{..}|interface{}ui

    func (name Type)* name (arg...) {...}
    打*號的部分是 接收器(receiver),用於擴展指定Type(必須是自定義類型)。

    type Point struct{ X, Y float64 }
    // traditional function
    func (p Point) Distance(q Point) float64 {
        return math.Hypot(q.X-p.X, q.Y-p.Y)
    }
    type Float64 float64 //
    func (p Float64) Distance(q Float64) float64 {
        return math.Abs(float64(p - q))
    }
    var x, y Float64 = 1.0, 2
    x.Distance(y)

    匿名函數:func(r rune) rune { return r + 1 }
    便捷操做

    import (
        "C"
        "fmt"
        "math"
    )
    const | var (
        AbsoluteZeroC Celsius = -273.15 // 絕對零度
        FreezingC     Celsius = 0       // 結冰點溫度
        BoilingC      Celsius = 100     // 沸水溫度
    )
    var a,b,c Type
  2. 控制結構
    if語句

    if a, b := 21, 3; a > b {
        fmt.Println("a>b ? true")
    }else {
    }
    
    for i, j := 1, 10; i < j; i,j=i+1,j+1 {  //死循環
        fmt.Println(i)
    }

    switch語句

    switch ch {
    case '0': 
        fallthrough   //必須是最後一個語句
    case '1':
        cl = "Int"
    case 'A': 
    case 'a':
        fallthrough
        cl = "ABC"    //error
    default:
        cl = "Other Char"
    }
  3. 類型轉換
    語法:

    <目標類型> ( <表達式> )
    <目標類型的值>,<布爾參數> := <表達式>.( 目標類型 ) // 安全類型斷言
    <目標類型的值> := <表達式>.( 目標類型 )  //非安全類型斷言
    var3 := int64(var1)
    var i interface{} = "TT"
    j, b := i.(int)
    if b {
        fmt.Printf("%T->%d\n", j, j)
    } else {
        fmt.Println("類型不匹配")
    }

基本類型

  1. 數組

    q := [...]int{1, 2, 3}
    q := [3]int{1, 2, 3} //等價
    fmt.Printf("%T\n", q) // "[3]int"
    
    r := [...]int{99: -1}// {下表:值},填充默認值
  2. Slice
    Slice(切片)表明變長的序列,序列中每一個元素都有相同的類型。一個slice類型通常寫做[]T,其中T表明slice中元素的類型;數組和slice之間有着緊密的聯繫。一個slice是一個輕量級的數據結構,提供了訪問數組子序列(或者所有)元素的功能,並且slice的底層確實引用一個數組對象。一個slice由三個部分構成:指針、長度和容量。
    array[i:j]來建立一個Slice,0 ≤ i≤ j≤ cap(s)

    array := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
    front := array[0:5]
    mid := array[3:8]
    tail := array[4:9]
    front[4] = 555 //3個數都被修改
    array[5] = 605 //會致使 mid,tail 修改

    注意

    array := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
        front := array[0:5]
        mid := array[3:8]
        tail := array[4:9]
        nf := append(tail, 66) //1.
        nf := append(mid, 66) //2.
        nf[0] = 5555
        fmt.Println(front, mid, tail, nf)
        //1. [1 2 3 4 601] [4 601 6 7 8] [601 6 7 8 9] [5555 6 7 8 9 66]
        //2. [1 2 3 5555 5] [5555 5 6 7 8] [5 6 7 8 66] [5555 5 6 7 8 66]

    當原數組夠用時,append會直接使用原來的空間。不夠時另開一片。

    []T是切片類型 [n]T是數組類型

  3. Map
    咱們也能夠用map字面值的語法建立map,同時還能夠指定一些最初的key/value:

    ages := make(map[string]int) // mapping from strings to ints
    ages := map[string]int{
        "alice":   31,
        "charlie": 34,
    }
  4. 結構體

    type Employee struct {
        ID        int
        Name      string
        Address   string
        DoB       time.Time
        Position  string
        Salary    int
        ManagerID int
    }
    
    var dilbert Employee
  5. 接口
    一類有相同方法的對象。

    package io
    type Reader interface {
        Read(p []byte) (n int, err error)
    }
    type Closer interface {
        Close() error
    }
    type ReadWriter interface {
        Read(p []byte) (n int, err error)
        Writer
    }
    
    var w io.Writer
    w = os.Stdout //使用接口

符號

關鍵字:
        break      default       func     interface   select
        case       defer         go       map         struct
        chan       else          goto     package     switch
        const      fallthrough   if       range       type
        continue   for           import   return      var
            
內建常量: true false iota nil

內建類型: int int8 int16 int32 int64
          uint uint8 uint16 uint32 uint64 uintptr
          float32 float64 complex128 complex64
          bool byte rune string error

內建函數: make len cap new append copy close delete
          complex real imag
          panic recover
  1. defer :延遲執行

    defer println("p1") //後被打印
        defer println("p2") //先被打印

    假設defer處聲明瞭一個變量,那麼在析構的時候執行內容。

  2. range :配合for使用

    for index, value := range mySlice {
        fmt.Println("index: " + index)
        fmt.Println("value: " + value)
    }
    • for index,char := range string {}

    • for index,value := range array {}

    • for index,value := range slice {}

    • for key,value := range map {}

抽象

不一樣於面向對象的語言先定義一個對象具備哪些抽象行爲再實現的思路。
GO是先實現一個對象,再檢查這個對象是否符合接口規範。

  1. 方法
    擴展某一個類型

    type Point struct{ X, Y float64 }
    
    // traditional function
    func Distance(p, q Point) float64 {
        return math.Hypot(q.X-p.X, q.Y-p.Y)
    }
    
    // same thing, but as a method of the Point type
    func (p Point) Distance(q Point) float64 {
        return math.Hypot(q.X-p.X, q.Y-p.Y)
    }
  2. 接口
    一類有相同方法的對象。

    package io
    type Reader interface {
        Read(p []byte) (n int, err error)
    }
    type Closer interface {
        Close() error
    }
    type ReadWriter interface {
        Read(p []byte) (n int, err error)
        Writer
    }

並行

  1. goroutine
    使用go關鍵字go

    f()    // call f(); wait for it to return
    go f() // create a new goroutine that calls f(); don't wait
  2. channel

    var ch chan int
    ch = make(chan int)    // unbuffered channel
    ch = make(chan int, 0) // unbuffered channel
    ch = make(chan int, 3) // buffered channel with capacity 3
    
    ch <- 2 //send
    a := ch //receive

    chan<- int表示一個只發送int的channel,只能發送不能接收。
    <-chan int表示一個只接收int的channel,只能接收不能發送。
    一個基於無緩存Channels的發送操做將致使發送者goroutine阻塞,直到另外一個goroutine在相同的Channels上執行接收操做,當發送的值經過Channels成功傳輸以後,兩個goroutine能夠繼續執行後面的語句。

  3. select

    select {
    case <-ch1:
        // ...
    case x := <-ch2:
        // ...use x...
    case ch3 <- y:
        // ...
    case <-time.After(10 * time.Second):
        //超時機制,不能與default一塊兒
    default:
        // ...
    }

調用C庫

cgo

/*
#cgo CFLAGS: -I/usr/include
#cgo LDFLAGS: -L/usr/lib -lbz2
#include <bzlib.h>
#include <stdlib.h>
bz_stream* bz2alloc() { return calloc(1, sizeof(bz_stream)); }
int bz2compress(bz_stream *s, int action,
                char *in, unsigned *inlen, char *out, unsigned *outlen);
void bz2free(bz_stream* s) { free(s); }
*/
import "C"

能夠添加一下編譯選項:

CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS , LDFLAGS

c代碼必須加以註釋且後面緊跟import "C"

在Go中使用C的類型

C.char C.schar (signed char) C.uchar (unsigned char) C.short C.ushort (unsigned short) C.int C.uint (unsigned int) C.long C.ulong (unsigned long) C.longlong (long long) C.ulonglong (unsigned long long) C.float C.double C.complexfloat (complex float) C.complexdouble (complex double)

若是是 struct, union, or enum 類型的,會添加前綴 struct_, union_, or enum_
struct。a{...};在go中變爲C.struct_a
C.sizeof_T 表示C中某種類型的長度

package main

// typedef int (*intFunc) ();
//
// int
// bridge_int_func(intFunc f)
// {
//        return f();
// }
//
// int fortytwo()
// {
//        return 42;
// }
import "C"
import "fmt"

func main() {
    f := C.intFunc(C.fortytwo)
    fmt.Println(int(C.bridge_int_func(f)))
    // Output: 42
}

在go中不能調用c中可變參數的函數

相關文章
相關標籤/搜索