Self study series of golang (3) — if, for, channel

Time:2021-4-16

Self study series of golang (3) — if, for, channel

Generally, the if statement performs two branch logic based on the result of a Boolean expression, just like the if statement in most languages.

There are always exceptions to go

//Writing method 1
if i:= getID(); i < currentID {
	execute some logic
} else {
	execute some other logic
}

//Writing method 2
var obj = map[string]interface{}
if val,ok := obj["id"]; ok {
	execute some logic
} else {
	execute some other logic
}

Writing method 1 means that an expression can be added before judging logic, such as getting ID, assigning it to I, and then participating in the subsequent judgment of whether it is less than the current ID.

Writing method 2 also means that before judging logic, you can add an expression to get the object ID (obj [“Id”]) to Val, but different from 1, the values of Val and OK are directly related. Val is the result of OK.

That is, OK must be a boolean type value, indicating whether Val = obj [“Id”] is assigned successfully. I think this feature is very good. You don’t need to obtain whether the value doesn’t exist or report an error.

For statement

For statements are generally represented as repeated execution blocks. It is composed of three parts, one is single condition controlled iteration, one is “for” statement, and the last is “range” statement.

ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
Condition = Expression .

After checking the information, we found that for has many usages

1、 Use a single conditional for statement

for a < b {
	a *= 2
}

This is the simplest, which means that as long as your condition evaluates to true, the code segment will be executed repeatedly. As shown above, as long as a < B, a * = 2 will always be executed. It is equivalent to a while loop.

2、 Use for clause

//Syntactic format
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
InitStmt = SimpleStmt .
PostStmt = SimpleStmt .

for i := 0; i < 10; i++ {
	f(i)
}

The for statement using the for clause is also controlled by conditions, but an additional init and post statement will be specified, just like allocating a number, which will increase or decrease automatically. If the condition is satisfied, the executor will run repeatedly.

As long as the initialization statement variable is not empty, it is evaluated before the first iteration. There are several points to note:

Any element in the for clause can be empty unless it is followed by a condition, in which case the semicolon cannot be lost. If the condition is default, it is equivalent to the condition being true. for example

For condition {exec()} is equivalent to for; condition; {exec()}
For {exec()} is equivalent to for true; {exec()}

3、 Use range clause

The for statement that uses the range clause represents the objects that are executed from, which are arrays, fragments, strings or maps, and values received on channels. If the iteration entry exists, it is assigned to the iteration variable.

RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .

The expression after the expression “range” is called a range expression. It may be an array, an array pointer, a fragment, a string, a map, or a channel granting receive operations. Just like assignment, if there are operands on the left, they must be addressable or mapped index expressions.

If the range expression is a channel, there is at most one iteration variable, otherwise there are at most two variables.If the last iteration variable is an empty identifier, it is equivalent to a range expression without this identifier.

The range expression x is evaluated once before the loop body starts, with one exception: if there is at most one iteration variable and Len (x) is Changshu, then the range expression will not be evaluated. Here is an example from the official website

var testdata *struct {
	a *[7]int
}
for i, _ := range testdata.a {
	// testdata.a is never evaluated; len(testdata.a) is constant
	// i ranges from 0 to 6
	f(i)
}

var a [10]string
for i, s := range a {
	// type of i is int
	// type of s is string
	// s == a[i]
	g(i, s)
}

var key string
var val interface{}  // element type of m is assignable to val
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
for key, val = range m {
	h(key, val)
}

// key == last map key encountered in iteration
// val == map[key]

var ch chan Work = producer()
for w := range ch {
	doWork(w)
}

// empty a channel
for range ch {}

Channel type

chanKey words: at first, the official website didn’t find a specific explanation for Chan, so it only knew that it was a key word. Later, after a data query, it was found that it was used to facilitate creationchannelType. The default value is nil.

Now that you know that Chan is used to createchannelYes, let’s seechannelDefinition of type:

A channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil.

In other words, the channel type provides a mechanism for concurrent functions to communicate by sending and receiving values of the specified element type. The value of unallocated channel is nil.

Let’s get to knowchanOperator for

Chan T // can be used to send and receive T-type values
chan

The official website also describes the following usage. To be honest, I don’t understand it very well

chan

Go language provides built-in functionsmakeThis function passes the channel type parameter and an optional capacity parameter

make(chan int, 100)

100 is the capacity value, which refers to the buffer size in the channel. If the value is 0, there is no buffer. In this case, only when the receiver and the sender are ready can they communicate successfully. Otherwise, as long as the buffer block is not full (push) or empty (receive), the buffered channel can successfully communicate.

Channel can be used by calling methodscloseclose. Multi value assignment reports whether the received value is before the channel is closed in the form of receive operator.

A single channel can be used to send statements, receive operators, and call built-in functionscapFunction sumlenFunction can also be used in any number of goroutlines without synchronization. A channel is a FIFO queue.

There are two points mentioned above, the send statement and the receive operator

Send statement

Simply put, it is to send a value to channel.

Ch means to send a value of 3 to the channel variable ch. If the channel is closed, a run time panic error will be reported.

Receive operator

For the channel type operands ch, receive the value of the operator

Now let’s look at some examples of Chan

var c chan int	// nil
C = make (Chan int) // initialization
fmt.Printf (the type of "C" is% T, CC) // Chan int
fmt.Printf (the value of "C" is% v, CC) // 0xc0000820c0

This shows that the value of Chan int is an address, like a pointer. But at present, I still don’t know what the specific usage is or where to use it?

When I try to read the value, I find that it seems to be blocking all the time

c

What I think is that Chan is blocked before receiving, so it has not executed the following output. So I added it to the backLet C receive. It turns out that the above output is still not executed.

Later, we checked the relevant information and found that the channel type is much like a channel, which is the relationship between consumers and producers.

So I wrote the following code

cc := make(chan int)
defer close(cc)
cc

Power off debugging found that (how to power off debugging in vscode, I will start another article to say) the program runs to CC CC: = make (Chan int, 100); can output the result value normally. But the concept does not say that without a buffer, you can’t send data normally.

When describing the send statement, it is said that the sender will not be processed until the receiver is ready. According to this result, the receiver is not ready. So how do you get the receiver ready?

I checked the data again and found that it was basically written in this way, based on the above code

cc := make(chan int)
defer close(cc)
go func() {
  cc

This is normal. Do you want the sender to exist as a function call?

I tried to change the immediate function to a normal function

cc := make(chan int)
defer close(cc)
fchan(cc)
i :=

It turns out that it still can’t. let’s put this problem aside. I’ll study it carefully when I have time later.

//Todo range can also handle Chan

Initialize array

[]type{}When I see this sentence, my heart is broken, because suddenly I see this kind of writing, I don’t know which feature it belongs to, and it’s not easy to look up the keyword information. At first I thought it was an array of type, followed by an empty object{}. But you can’t see this concept through the features. Later, I wrote an example to see the specific output

var sa = []string{}
fmt.Printf ("the value of SA is% v / N", SA) // the value of SA is []

It turns out to be an array with no objects. Then I tried to get rid of the back{}It is found that the compiler can’t pass at all. This is to initialize a string array.

This article is synchronized to: https://github.com/MarsonShine/GolangStudy/blob/master/src/QPaint/doc/golang-study-3.md

Recommended Today

Envoy announced alpha version of native support for windows

Author: sunjay Bhatia Since 2016, porting envoy to the windows platform has been an important part of the projectOne of the goalsToday, we are excited to announce the alpha version of envoy’s windows native support. The contributor community has been working hard to bring the rich features of envoy to windows, which is another step […]