Administrator
发布于 2023-03-07 / 37 阅读
0
0

Golang---Block & Control Structure

Block

block分级

  • package block
  • file block
  • local block . generally, a pair of braces {} encloses a local block

img

上面的图中,func IsSqr和 const N func Sleep,都是属于package block;
而square.go sleep.go import math import time,都是属于file block;


同一个package下,不同file之间相互调用,是不需要import的。同时,也不需要让function的名字,首字母是大写的。

但是,不同package下,相互调用,是需要import的,同时,function的名字,首字母需要大写

针对package block 和 file block,我们来看一个例子

image-20230307162554989

PetShop.go:

package main

import (
	"fmt"
	"raw-demo/src/animalcenter"
)

func main() {
	abbrevName := "大黄"
	kind := "dog"
	completeName := animalcenter.GetAnimalCompleteName(kind, abbrevName)
	fmt.Println(completeName)
}

Animal.go:

package animalcenter

func isAnimal(kind string) bool {
	if "cat" == kind {
		return true
	} else if "dog" == kind {
		return true
	} else {
		return false
	}
}

// 这个函数,名字的首字母必须大写,表示export这个函数,这样,在别的package才能调用这个函数
func GetAnimalCompleteName(kind string, abbrevName string) string {
	if !isAnimal(kind) {
		return ""
	} else {
		return getDogName(abbrevName)
	}

}

Dog.go:

package animalcenter

func getDogName(abbrevName string) string {
	return "dog_" + abbrevName
}

Shadowing Variables

A shadowing variable is a variable that has the same name as a variable in a containing block.

As long as the shadowing variable exists, you cannot access a shadowed variable.

package main

import "fmt"

func main()  {
	x := 10
	if (x > 5) {
		fmt.Println(x)
		x := 5
		fmt.Println(x)

	}
	fmt.Println(x)

}

输出

10
5
10
that’s because := only reuses variables that are declared in the current block. 

When using :=, make sure that you do not have any variables from an outer scope on the left hand side, unless you intend to shadow them.

If

declare variable scope to if/else statements

if n := rand.Intn(10); n == 0 {
	fmt.Println("That's too low")
} else if n > 5 {	
	fmt.Println("That's too big:", n)
} else {	
	fmt.Println("That's a good number:", n)
}

What Go adds is the ability to declare variables that are scoped to the condition and to both the if and else blocks.

Once the series of if/else statements ends, n is undefined.

For

four different formats:

  • A complete, C-style for
  • A condition-only for
  • An infinite for
  • for-range

A complete, C-style for

package main

import "fmt"

func main() {
	for i := 0; i < 10; i++ {
		fmt.Print(i)
	}

}

Just like the if statement, there are no parenthesis around the parts of the for statement.

The first is an initialization that sets one or more variables before the loop begins. There are two important details to remember about the initialization section. First, you must use := to initialize the variables; var is not legal here. Second, just like variable declarations in if statements, you can shadow a variable here.

The second part is the comparison. This must be an expression that evaluates to a bool. It is checked immediately before the loop body runs, after the initialization, and after the loop reaches the end. If the expression evaluates to true, the loop body is executed.

The last part of a standard for statement is the increment. You usually see something like i++ here, but any assignment is valid. It runs immediately after each iteration of the loop, before the condition is evaluated.

The Condition-only for Statement

Go allows you to leave off both the initialization and the increment in a for statement.

That leaves a for statement that functions like the while statement found in C, Java,

package main

import "fmt"

func main() {
	i := 1
	for i < 10 {
		fmt.Println(i)
		i *= 2

	}
}

输出

1
2
4
8

The Infinite for Statement

func main() {
	for {
		fmt.Println("Hello")
	}
}

The for-range Statement

What makes a for-range loop interesting is that you get two loop variables.

The first variable is the position in the data structure being iterated, while the second is value at that
position.

The idiomatic names for the two loop variables depend on what is being looped over. When looping over an array, slice, or string, an i for index is commonly used. When iterating through a map, k (for key ) is used instead.

package main

import "fmt"

func main() {
	teams := []int{2, 4, 6, 8, 10, 12}
	for i, v := range teams {
		fmt.Println(i, v)
	}
}

输出

0 2
1 4
2 6
3 8
4 10
5 12
package main

import "fmt"

func main() {
	teams := []int{2, 4, 6, 8, 10, 12}
	for _, v := range teams {
		fmt.Println(v)
	}
}

输出

2
4
6
8
10
12

package main

import "fmt"

func main() {
	citys := map[string]bool{
		"nanjing":  true,
		"hefei":    true,
		"shenzhen": false,
	}
	for k, _ := range citys {
		fmt.Println(k)
	}
}

输出

hefei
shenzhen
nanjing

func main() {
	city := "合肥"
	for i, v := range city {
		fmt.Println(i, v, string(v))
	}

}

输出

0 21512 合
3 32933 肥

上面的例子中,中文字符是需要3个byte来表示的,在这种多byte表示的字符中,for-range iterator的是rune,而不是byte。这一点,从i 和 v的值,就能看出来。

What we are seeing is special behavior from iterating over a string with a for-range loop. It iterates over the runes , not the bytes.

The for-range Value is a Copy

You should be aware that each time the for-range loop iterates over your compound type, it copies the value from the compound type to the value variable. Modifying the value
variable will not modify the value in the compound type
evenVals := []int{2, 4, 6, 8, 10, 12}
for _, v := range evenVals {	
	v *= 2
}
fmt.Println(evenVals) // 2 4 6 8 10 12]

Switch

the basics of using switch

don’t need to put a break statement at the end of each case clause,auto provide break effect

1.you don’t need to put a break statement at the end of each case clause,auto provide break effect




2.you have an empty case (like we do in our sample program when the length of our argument is 6, 7, 8, or 9 characters), what happens? 

In Go, an empty case means nothing happens. 

That’s why we don’t see any output from our program when we use octopus or gopher as the
parameter.
package main

import "fmt"

func main() {
	words := []string{"a", "cow", "smile", "gopher", "octopus", "anthropologist"}

	for _, v := range words {
		switch size := len(v); size {
		case 1, 2, 3, 4:
			fmt.Println(v, "this is a short word")
		case 5:
			wordLen := len(v)
			fmt.Println(v, "is exactly the right length", wordLen)
		case 6, 7, 8, 9:
		default:
			fmt.Println(v, " is a long word")

		}

	}

}

输出

a this is a short word
cow this is a short word
smile is exactly the right length 5
anthropologist  is a long word

The Blank switch

A regular switch only allows you to check a value for equality.

A blank switch allows you to use any boolean comparison for each case

unlike a regular switch, you can write logical tests for your cases.
words := []string{"hi", "salutations", "hello"}

for _, word := range words {	
    switch wordLen := len(word); {	
        case wordLen < 5:		
        	fmt.Println(word, "is a short word!")	
        case wordLen > 10:		
        	fmt.Println(word, "is a long word!")	
        default:		
        	fmt.Println(word, "is exactly the right length.")	
    }
}

评论