アペンド
機能は、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)
}
}
}
参照によって渡されるスライス広がり関数
コードのテスト
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)
最初の非緩衝チャネル、第二チャネルがバッファリングされます
タスクの実行は、ケースを考慮する必要があります。
- システム停止
- 完成(完全または失敗)
- タイムアウト
ランナー
ランナーは、タイムアウト割り込み機能が付属しています
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
}