0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Go]シャドーイング、制御構文

Posted at

概要

  • 前回のつづき
  • 今回は、変数のシャドーイング(隠蔽)や、制御構文、関数についての学習
  • 今回もJavaやts(typeScript)と比較しつつ、進める。

インプット資料

シャドーイング

  • ブロックの外と内で同じ変数を宣言した場合の動作
    • 内では、外の変数はシャドーイング(隠蔽)される。そのため、外の変数はアクセスできなくなる
    • 内を抜けたら、外の変数が参照される
  • バグの温床になるので、シャドーイングはしない。
	x := 10
	{
		fmt.Println(x) //10
		x := 5
		fmt.Println(x) //5 -> x:=10のシャドーイング発生
	}
	fmt.Println(x) // 10 → x:=10のシャドーイング解除
  • (補足)Javaの場合
    • ブロック外と内での変数宣言は、重複ローカル変数となり、コンパイルエラーになる。
    • クラス変数とローカル変数で同じ変数を宣言した場合は、thisで区別する。
    • シャドーイングが発生するのは、継承関係にあるクラスのクラス変数が重複した場合。
      • ※Goではクラスの継承自体がないので、そもそもで発生しない。

制御構文

  • 共通して、条件を記載する箇所に()は不要。

if

  • if文の条件の前に、変数を宣言できる。
  • 宣言した変数はif-else内のブロックスコープとなる
	rand.NewSource(time.Now().UnixNano())
	// ブロック内のみ有効な変数「n」
	if n := rand.Intn(10); n == 5 {
		fmt.Println("nは5",n)
	} else if n < 5 {
		fmt.Println("nは5未満",n)
	} else {
		fmt.Println("nは5より上",n)
	}
	// ブロック外ではエラーとなる
	//fmt.Println("nは",n)

for

  • 繰り返しはfor文でのみ行う。whileはない。(代替する書き方はもちろんある。)
  • 他の言語同様、breakやcontinueもある。gotoやラベル遷移もあるが、処理が追いづらくなるので、使用箇所には注意する。
  • for文には以下の4種類ある。
    • 通常のfor文
    • 拡張for文
      • for-range構文。配列やsliceなどを走査する場合に利用する。
      • 引数を2つ(indexとvalue)とる。index不要の場合は、変数名を_にする(tsと同様)
      • for-rangeで宣言した値はコピーであるため、変更しても元の配列には影響しない( =イミュータブル)
    • 条件のみfor文
      • while文の代わり
    • 条件なしfor文
      • 無限ループ
	// 通常のfor文
	for i := 0; i < 5; i++ {
		fmt.Println(i)
	}

	// 拡張for文
	evenVal := []int{1,2,3,4,5,6}
	// index不要の場合「_」にする。なお、2つめ(value)が不要の場合は宣言しないでよい。
	for _, v := range evenVal {
		if v % 2 == 0 {
			fmt.Println(v)
		}
	}

	// 条件のみfor文(while文)
	i := 2
	for i < 10 {
		fmt.Println(i)
		i = i * 2
	}

	// 条件なしfor文(無限ループ)
	n := 1;
	for {
		fmt.Println(n)
		if n > 5 {
			break
		}
		n++
	}

switch

  • switch内で有効となる変数宣言ができる
  • csse文ではbreak記載しない。フォールスルーしたいときは、カンマで区切って、一つのcase式で複数の値を列挙する
  • switch文に条件式を書かなくてもよい。(ブランクswitch)その場合、case文に条件式を書ける。
  • 特定の変数に対する条件分岐の場合は、if文より、switch文を推奨

	rand.NewSource(time.Now().UnixNano())

	// ブロック内のみ有効な変数「n」
	switch n := rand.Intn(12); n {
	case 2,4,6,8,10:
		fmt.Println("10までの偶数です。",n)
	case 1,3,5,7,9:
		fmt.Println("10までの奇数です。",n)
	default:
		fmt.Println("その他。",n)
	}
	// ブロック外ではエラーとなる
	//fmt.Println("nは",n)

	// ブランクswitch
	// switch内で条件式を書かず、case内に書くこともできる
	switch n := rand.Intn(12); {
	case n % 2 == 0 && n <= 10:
		fmt.Println("10までの偶数です。",n)
	case n % 2 != 0 && n <= 10:
		fmt.Println("10までの奇数です。",n)
	default:
		fmt.Println("その他。",n)
	}

おわりに

  • 制御ブロック内のみで有効な変数を宣言できるのは便利
  • while文をfor文に統合したのは、シンプルでよいと思う。
    • 元々while文はbreak条件の見通しが悪いから使用頻度も低いので。
  • switch文が便利で使いやすくなったが、if文との使い分けが難しくなりそう。
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?