Go言語での遅延遅延メカニズム

    Go言語では、特定のメソッド、関数、またはパラメーターの処理を遅らせる必要がある場合があり、その場合はdeferキーワードが必要になります。

遅延遅延の影響

1.遅延機能

  • 関数に複数のdeferステートメントを追加できます。
    1)関数が最後まで実行されると、これらのdeferステートメントは逆の順序で実行され、最後に関数が戻ります。特に、リソースを開くための操作を行う場合、エラーが発生した場合は事前に戻る必要があります。戻る前に対応するリソースを閉じる必要があります。そうしないと、リソースのリークやその他の問題が発生しやすくなります
    。2)延期の呼び出しが多い場合は、次に、deferはlast-in-first-outモードを採用ます
    。3)メソッドを終了するときは、defer自体を実行します(エラーが報告されたときにも実行されます)。

    ケース1.遅延のmain関数で、関数
//myDeferFuc.go support funcを呼び出します。()のmain()の遅延

// myDeferDes project main.go
package main

import (
	"fmt"
)

func funA() {
	fmt.Println("我是funA()...")
}

func funB() {
	fmt.Println("我是funB()...")
}

func funC() {
	fmt.Println("我是funC()...")
}

func main() {
	defer funA()
	funB()
	funC()
	fmt.Println("main is over...")
}


    効果は次のとおりです。


図(1)main()でのfunc A()の実行の遅延

    ケース2.関数delayは関数を呼び出します
//myDeferFunc2.goFunctions()で終了したfuncの実装の遅延

// myDeferMax project main.go
package main

import (
	"fmt"
)

func finished() {
	fmt.Println("结束!")
}

func largest(s []int) {
	defer finished()
	fmt.Println("开始寻找最大数...")
	max := s[0]
	for _, v := range s {
		if v > max {
			max = v
		}
	}
	fmt.Printf("%v中的最大数为:%v\n", s, max)
}

func main() {
	s1 := []int{78, 109, 2, 563, 300}
	largest(s1)
}


    効果は次のとおりです。


図(2)サブ関数でfuncfinished()の呼び出しを遅らせる

第二に、遅延法

  • deferを使用して、メソッドの呼び出しを遅らせることができます

    ケース3.メイン関数
//myDeferMethod.goでメソッドの呼び出しを遅らせる

// myDeferMethod project main.go
package main

import (
	"fmt"
)

type person struct {
	firstName string
	lastName  string
}

func (per person) fullName() {
	fmt.Printf("%s %s\n", per.firstName, per.lastName)
}

func main() {
	per := person{"Steven", "Wang"}
	defer per.fullName()
	fmt.Printf("Welcome, ")
}


    効果は次のとおりです。


図(3)メイン関数のfullName()メソッドの呼び出しを遅らせる

3、パラメータ転送の遅延(パラメータの保持)

  • Deferは、宣言前にパラメーターを保持し、関数の最後に実行されます。

    ケース4.パラメーターaとbを保持し、defer
// myDeferMethod.goを使用します

// myDeferParam project main.go
package main

import (
	"fmt"
)

func printAdd(a, b int) {
	fmt.Printf("延迟函数中: 参数a,b分别为%d,%d, 两数之和为:%d\n", a, b, a+b)
}

func main() {
	a := 5
	b := 6
	defer printAdd(a, b) //延迟参数a,b的传递
	a = 10
	b = 7
	fmt.Printf("延迟函数执行前: 参数a,b分别为%d,%d, 两数之和为:%d\n", a, b, a+b)

}


    効果は次のとおりです。


図(4)deferは、宣言される前にパラメーターを保持し、関数の最後に実行されます

第四に、スタックの遅延

  • 関数に複数の遅延呼び出しがある場合、それらはスタックに追加され、Last In First Out(LIFO)の順序で実行されます。

    ケース
5.deferを使用して文字列の逆順を実現する//myDeferReveser.go

// myDeferHeap project main.go
package main

import (
	"fmt"
)

func ReverseString(str string) {
	for _, v := range []rune(str) {
		defer fmt.Printf("%c", v)
	}
}

func main() {
	name := "StevenWang欢迎学习区块链"
	fmt.Println("原始字符串: ", name)
	fmt.Println("翻转后的字符串: ")
	ReverseString(name)
}


    効果は次のとおりです。


図(5)リバースストリング

5、アプリケーションを遅らせる

  • WaitGroupの使用をお勧めします

    ケース6アプリケーションを遅延させる
//myDeferApp.go

// myDeferApp project main.go
package main

import (
	"fmt"
	"sync"
)

type rect struct {
	length int
	width  int
}

func (r rect) area(wg *sync.WaitGroup) {
	defer wg.Done()
	if r.length < 0 {
		fmt.Printf("rect %v's length should be greater than zero\n", r)
		return
	}

	if r.width < 0 {
		fmt.Printf("rect %v's width should be greater than zero\n", r)
		return
	}

	area := r.length * r.width
	fmt.Printf("rect %v's area %d\n", r, area)
}

func main() {
	var wg sync.WaitGroup
	r1 := rect{-67, 89}
	r2 := rect{5, -67}
	r3 := rect{8, 9}
	rects := []rect{r1, r2, r3}
	for _, v := range rects {
		wg.Add(1)
		go v.area(&wg)
	}
	wg.Wait()
	fmt.Println("All go routines finished executing")
}


    効果は次のとおりです。


図(6)アプリケーションの遅延

おすすめ

転載: blog.csdn.net/sanqima/article/details/108910280