実用的な言語の抜粋を行きます

アペンド

機能は、appendインテリジェントボリュームの成長基盤となる配列を扱います。容量が1000個の要素のスライスに満たない場合は、必ず容量を乗算されます。1000以上の要素の数たら、設備利用率は、1.25に増加します
つまり、それぞれ増加25%容量のは、言語の進化とともに、この成長アルゴリズムが変更されることがあります。

テストコード&結果

func main() {
    l1 := []int{0: 1}
    k := 1
    last := 0
    for k < 2000 {
        l1 = append(l1, k)
        k++
        if cap(l1) != last {
            fmt.Println(k, cap(l1))
            last = cap(l1)
        }
    }
}

結果.PNG

参照によって渡されるスライス広がり関数

コードのテスト

func foo(list []int) {
    for i := 0; i < len(list); i++ {
        list[i] = 10 + i
    }
    return
}
func main() {
    list := []int{0, 1, 2}
    foo(list)
    fmt.Printf("%v", list)
}

// 结果
[10, 11, 12]

スライスとポインタ

64位機械のフレームワークは、スライス必要24字节メモリ、ポインタフィールドのニーズ8字节、及び各長必要の能力を8字节

##メソッドのセット

値| メソッドレシーバ

T |(TのT)

T | (T T)及び(Tの T)

ポイントT类型的值的方式のセットは含まれてい值接收者メソッドの宣言を。
ポインティングT类型的指针方法のセットは含ま值接收者宣言と指针接收者メソッド宣言を。

によって複雑

goデフォルトでは、使用可能な各言語ランタイムのための物理プロセッサを割り当てられます逻辑处理器
あなたが作成した場合goroutineと実行する準備が、これはgoroutineのグローバル実行キュースケジューラになります。その後、スケジューラは、これらのキューはなりgoroutine論理プロセッサ、および対応するローカル実行キューへの論理プロセッサに割り当てられています。

論理プロセッサ

ローカル実行キュー

スケジューラ

使用するgo build -raceコンパイラに競争検出フラグを
プログラムを実行するために、./go_start.exe警告が。

それは使用することができますatomicし、syncメソッドや関数のパッケージ保証スレッドの安全性の下で

unbuffered := make(chan int)
buffered := make(chan string, 10)

最初の非緩衝チャネル、第二チャネルがバッファリングされます

タスクの実行は、ケースを考慮する必要があります。

  1. システム停止
  2. 完成(完全または失敗)
  3. タイムアウト

ランナー

ランナーは、タイムアウト割り込み機能が付属しています

type Runner struct {
    interrupt chan os.Signal

    complete chan error

    timeout <-chan time.Time

    tasks []func(int)
}

var ErrTimeOut = errors.New("received timeout")
var ErrInterrupt = errors.New("received interrupt")

// new a Runner
func New(d time.Duration) *Runner {
    return &Runner{
        interrupt: make(chan os.Signal, 1),
        complete:  make(chan error),
        timeout:   time.After(d),
    }
}

func (r *Runner) Add(tasks ...func(int)) {
    r.tasks = append(r.tasks, tasks...)
}

func (r *Runner) Start() error {
    signal.Notify(r.interrupt, os.Interrupt)

    go func() {
        r.complete <- r.run()
    }()

    select {
    case err := <-r.complete:
        return err
    case <-r.timeout:
        return ErrTimeOut
    }
}

func (r *Runner) run() error {
    for id, task := range r.tasks {
        if r.gotInterrupt() {
            return ErrInterrupt
        }
        task(id)
    }
    return nil
}

func (r *Runner) gotInterrupt() bool {
    select {
    case <-r.interrupt:
        signal.Stop(r.interrupt)
        return true
    default:
        return false
    }
}

プール

リソース管理プール

package pool

import (
    "errors"
    "io"
    "log"
    "sync"
)

type Pool struct {
    m         sync.Mutex
    resources chan io.Closer
    factory   func() (io.Closer, error)
    closed    bool
}

var ErrPoolClosed = errors.New("Pool has been closed")

func New(fn func() (io.Closer, error), size uint) (*Pool, error) {
    if size <= 0 {
        return nil, errors.New("size value too small")
    }
    return &Pool{
        factory:   fn,
        resources: make(chan io.Closer, size),
    }, nil
}

// get a resource
func (p *Pool) Acquire() (io.Closer, error) {
    select {
    case r, ok := <-p.resources:
        log.Println("Acquire:", "shared Resource")
        if !ok {
            return nil, ErrPoolClosed
        }
        return r, nil
    default:
        log.Println("Acquire:", "New Resource")
        return p.factory()
    }
}

// release to reasoure
func (p *Pool) Release(r io.Closer) {
    p.m.Lock()
    defer p.m.Unlock()

    if p.closed {
        r.Close()
        return
    }

    select {
    case p.resources <- r:
        log.Println("Release:", "In queue")
    default:
        log.Println("Release:", "Closing")
        r.Close()
    }
}

// Close
func (p *Pool) Close() {
    p.m.Lock()
    defer p.m.Unlock()
    if p.closed {
        return
    }
    p.closed = true
    close(p.resources)

    for r := range p.resources {
        r.Close()
    }
    return
}

おすすめ

転載: www.cnblogs.com/Draymonder/p/11106701.html