ホームページ >バックエンド開発 >Golang >Golang のプロセス制御を簡単に分析した記事

Golang のプロセス制御を簡単に分析した記事

青灯夜游
青灯夜游転載
2022-11-25 21:07:206341ブラウズ

この記事では、Golang について説明し、Go 言語の基本的なプロセス制御について説明します。

Golang のプロセス制御を簡単に分析した記事

Go 言語によるフロー制御には主に以下の内容が含まれます。

  • 条件文 if
  • 条件文 switch
  • 条件文 select
  • ループ文 for
  • ループ文の範囲
  • ループ制御 Goto、Break、Continue

[プログラミング チュートリアル]おすすめ :プログラミング教育]

1. Go の条件文 if

if 条件言語 判定形式は次のとおりです:

if 表达式1 {
    分支1
} else if 表达式2 {
    分支2
} else{
    分支3
}

フロントエンドの学生は比較的 js に精通している必要があります。js と比較すると、go 式は括弧 () を削除しますが、同時に与えますいくつかの制約と if対応する左括弧 { は、if および式 と同じ行に配置する必要があります。{ を他の場所に配置すると、コンパイルエラーを引き起こします。同様に、else と一致する {else と同じ行に記述し、else も記述する必要があります。前の if または else if と同じ行にあります。 右側の中括弧は同じ行にあります。

x := 0

// if x > 10        // Error: missing condition in if statement
// {
// }

if n := "abc"; x > 0 {     // 初始化语句未必就是定义变量, 如 println("init") 也是可以的。
    println(n[2])
} else if x < 0 {    // 注意 else if 和 else 左大括号位置。
    println(n[1])
} else {
    println(n[0])
}



 *不支持三元操作符(三目运算符) "a > b ? a : b"。
 
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 10
   /* 使用 if 语句判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" )
   }
   fmt.Printf("a 的值为 : %d\n", a)
}


以上代码执行结果为:
a 小于 20
a 的值为 : 10

2. 条件ステートメント switch

switch ステートメントは、さまざまな条件に基づいてさまざまなアクションを実行するために使用され、各ケース ブランチは一意です。一致するまで上から下に 1 つずつテストします。 Golang スイッチのブランチ式は、定数に限定されず、任意のタイプにすることができます。 Break は省略でき、デフォルトでは自動的に終了します。

package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }

   switch {
      case grade == "A" :
         fmt.Printf("优秀!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" )
   }
   fmt.Printf("你的等级是 %s\n", grade )
}



以上代码执行结果为:
优秀!
你的等级是 A

3. 条件ステートメント select

select ステートメントは switch ステートメントと似ていますが、select は実行可能なケースをランダムに実行します。実行するケースがない場合は、実行するケースができるまでブロックされます。

select は Go の制御構造で、通信に使用される switch ステートメントに似ています。各ケースは、送信または受信のいずれかの通信操作である必要があります。 select は実行可能なケースをランダムに実行します。実行するケースがない場合は、実行するケースができるまでブロックされます。デフォルト句は常に実行可能である必要があります。

次に、select ステートメントの構文について説明します。

    每个case都必须是一个通信
    所有channel表达式都会被求值
    所有被发送的表达式都会被求值
    如果任意某个通信可以进行,它就执行;其他被忽略。
    如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。
    否则:
    如果有default子句,则执行该语句。
    如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
package main

import "fmt"

func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   }    
}



以上代码执行结果为:

 no communication

select はチャネルのデータ フローを監視できます

select の使用法は switch 構文と非常によく似ています。新しいものは select から始まります select ブロックでは、各選択条件を case 文で記述します

等価比較を利用した任意の条件を選択できる switch 文と比べて、select には制約が多くあります 最大の制約つまり、各 case ステートメントは IO 操作でなければなりません

 select { //不停的在这里检测
    case <-chanl : //检测有没有数据可以读
    //如果chanl成功读取到数据,则进行该case处理语句
    case chan2 <- 1 : //检测有没有可以写
    //如果成功向chan2写入数据,则进行该case处理语句


    //假如没有default,那么在以上两个条件都不成立的情况下,就会在此阻塞//一般default会不写在里面,select中的default子句总是可运行的,因为会很消耗CPU资源
    default:
    //如果以上都没有符合条件,那么则进行default处理流程
    }

select ステートメントでは、Go は各送信ステートメントと受信ステートメントを最初から最後まで順番に評価します。

いずれかのステートメントが実行を継続できる (つまり、ブロックされていない) 場合は、実行可能なステートメントのいずれかを選択して使用します。ステートメントを実行できない場合 (つまり、すべてのチャネルがブロックされている場合)、次の 2 つの状況が考えられます。 ① デフォルト ステートメントが指定されている場合、デフォルトのプロセスが実行され、プログラムの実行は select の後から開始されます。ステートメント。ステートメント。 ②default ステートメントがない場合、select ステートメントは少なくとも 1 つのケースが続行できるまでブロックされます。

典型的な使用法 - タイムアウト判定

//比如在下面的场景中,使用全局resChan来接受response,如果时间超过3S,resChan中还没有数据返回,则第二条case将执行
var resChan = make(chan int)
// do request
func test() {
   select {
   case data := <-resChan:
       doData(data)
   case <-time.After(time.Second * 3):
       fmt.Println("request time out")
   }
}

func doData(data int) {
   //...
}

4.

# のループ ステートメントは、 if と同様、js と比較すると、go 言語の for ループも括弧 () を削除するなど、その他の点では大きな違いはありません。

package main

import "fmt"

func main() {

   var b int = 15
   var a int

   numbers := [6]int{1, 2, 3, 5}

   /* for 循环 */
   for a := 0; a < 10; a++ {
      fmt.Printf("a 的值为: %d\n", a)
   }

   for a < b {
      a++
      fmt.Printf("a 的值为: %d\n", a)
      }

   for i,x:= range numbers {
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }   
}


以上实例运行输出结果为:

    a 的值为: 0
    a 的值为: 1
    a 的值为: 2
    a 的值为: 3
    a 的值为: 4
    a 的值为: 5
    a 的值为: 6
    a 的值为: 7
    a 的值为: 8
    a 的值为: 9
    a 的值为: 1
    a 的值为: 2
    a 的值为: 3
    a 的值为: 4
    a 的值为: 5
    a 的值为: 6
    a 的值为: 7
    a 的值为: 8
    a 的值为: 9
    a 的值为: 10
    a 的值为: 11
    a 的值为: 12
    a 的值为: 13
    a 的值为: 14
    a 的值为: 15
    第 0 位 x 的值 = 1
    第 1 位 x 的值 = 2
    第 2 位 x 的值 = 3
    第 3 位 x 的值 = 5
    第 4 位 x 的值 = 0
    第 5 位 x 的值 = 0

5. ループ ステートメントの range

Golang の range はイテレータ操作と似ており、(インデックス、値) または (キー、価値)。

for ループの範囲形式は、スライス、マップ、配列、文​​字列などを反復処理できます。形式は次のとおりです。

for key, value := range oldMap {
    newMap[key] = value
}
package main

func main() {
    s := "abc"
    // 忽略 2nd value,支持 string/array/slice/map。
    for i := range s {
        println(s[i])
    }
    // 忽略 index。
    for _, c := range s {
        println(c)
    }
    // 忽略全部返回值,仅迭代。
    for range s {

    }

    m := map[string]int{"a": 1, "b": 2}
    // 返回 (key, value)。
    for k, v := range m {
        println(k, v)
    }
}

输出结果:

    97
    98
    99
    97
    98
    99
    a 1
    b 2

for と for range の違いは何ですか?

主な理由は、使用シナリオが異なることです

for は配列とスライス、およびキーが整数増分であるマップの走査、string

for range の走査では、for で実行できることはすべて実行できますが、キーが文字列型であるマップの走査など、for で実行できないことも実行できます。

6. ループ制御 Goto、Break、Continue

ループ制御ステートメント

Loop制御ステートメントは、ループ本体内のステートメントの実行プロセスを制御できます。

GO 言語は、次のループ制御ステートメントをサポートします:

Goto、Break、Continue

    1.三个语句都可以配合标签(label)使用
    2.标签名区分大小写,定以后若不使用会造成编译错误
    3.continue、break配合标签(label)可用于多层循环跳出
    4.goto是调整执行位置,与continue、break配合标签(label)的结果并不相同

break(ループから抜け出す) : continue (次のサイクルを継続) break ステートメントは、forswitch、および select のコード ブロックを終了できます。 break ステートメントでは、ステートメントの後にラベルを追加して、特定のラベルに対応するコード ブロックの終了を示すこともできます。ラベル要件は、対応する for, switch で定義する必要があります および select コード ブロック。

continue(继续下次循环)continue语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for循环内使用。在 continue语句后添加标签时,表示开始标签对应的循环

goto语句通过标签进行代码间的无条件跳转。goto语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go语言中使用goto语句能简化一些代码的实现过程。 例如双层嵌套的for循环要退出时:

func gotoDemo1() {
	var breakFlag bool
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// 设置退出标签
				breakFlag = true
				break
			}
			fmt.Printf("%v-%v\n", i, j)
		}
		// 外层for循环判断
		if breakFlag {
			break
		}
	}
}

使用goto语句能简化代码:

func gotoDemo2() {
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// 设置退出标签
				goto breakTag
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	return
	// 标签
breakTag:
	fmt.Println("结束for循环")
}

结束:

再次提醒,需要进技术交流群的同学,可以加我微信fangdongdong_25,需要进前端工程师交流群的备注“前端”,需要进go后端交流群的备注“go后端”

【相关推荐:Go视频教程

以上がGolang のプロセス制御を簡単に分析した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。