This is the 8th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

The assignment

An assignment statement is used to update the value referred to by a variable. In its simplest form, it consists of an assignment symbol =, a variable to the left of the symbol, and an expression to the right of the symbol

X = 1// Named variable *p = true // Indirect variable person. Name = "Bob" // Struct member count[x] = count[x] * scale // Elements of array or slice or mapCopy the code

Each arithmetic and binary operator has a corresponding assignment operator. For example, the last statement above can be rewritten as

count[x] *= scale
Copy the code

It avoids repeating the variable itself in the expression. Numeric variables can also be incremented and decremented by ++ and – statements

V := 1 v++ // = 1 v++ // = 1 v++Copy the code

Multiple assignments

Another method of assignment is multiple assignment, which allows several variables to be assigned at once. This form is especially useful when variables appear on both sides of an assignment, for example, when swapping the values of two variables:

X,y = y, x a[I], a[j] = a[j], a[I] func GCD (x,y int) int{for y! =0 {x,y = y, x%y} return x} func fib(n int) int {x,y :=0, 1 for I :=0; i < n; i++ { x, y = y, x+y } return x }Copy the code

Multiple assignments can make a normal assignment sequence more compact

i, j, k = 1, 2, 3
Copy the code

However, if the expression is more complex, you should avoid this multiple assignment; a series of independent statements is easier to read. For example, some types of expressions may produce multiple values (such as calling a function that returns multiple values). When such a call is used in an assignment statement, the number of variables on the left needs to be the same as the return value of the function

F, err = os.open ("foo.txt")// The function call returns two valuesCopy the code

Usually functions use extra return values to indicate some error condition, such as an error type returned by os.open (), or a variable of type bool, usually called OK

V, ok = m[key] //map query v, ok = x.(T)// type assertion v, ok = <=ch The empty identifier _, err = IO.Copy(DST, SRC) _, ok = x.(T)Copy the code

Sex can be assigned a value

Assignment statements are explicit assignments, but there are many places in a program where assignment is implicit. For example, a function call implicitly assigns the value of an argument to a variable that corresponds to the argument. A return statement implicitly assigns the return operand to the result variable. Literal expressions of compound types, such as slice

When you think or speculate about something := []string{"gold", "silver", "bronze"} implicitly assigns a value to each element, When you think or speculate [0] = "gold" [1] = "silver" [2] = "bronze"Copy the code

An assignment, whether implicit or explicit, is legal if the type declaration on the left and on the right is the same. Assignment is legal only if the value is assignable to the variable type

Assignability has different rules depending on the type. The types must match exactly, and nil can be assigned to any interface variable or reference type. Constants have more flexible assignment rules to avoid conversions that are displayed (more on that later)

Comparison of two values using == and ≠ is related to assignability: in any comparison, the first operand must be assignable to the type of the second operand, or the other way around

Type declaration

The type of a variable or expression defines the properties that these values should have, such as their size (how many bits or elements, etc.), how they are expressed internally, and what operations can be performed on them

In any program, there are variables that use the same representation, but with very different meanings. For example, the int type can be used to represent the index, timestamp, file descriptor, or month of a loop. Type FLOAT64 can represent speed or temperature to a few decimal places. The string type can represent a password or a color name

Type declares a new named type that uses the same underlying type as an existing type. Named types provide a way to distinguish between different or incompatible uses of underlying types so that they are not inadvertently mixed

type name underlying-type
Copy the code

Type declarations typically occur at the package level, where the named type is visible throughout the package. If you want it to be used across packages, capitalize the first letter of name

In the following example, the values of different units of measurement are converted to different types

Package TempCONV Type Celsius Float64 Type Fahrenheit Float64 const(AbsoluteZeroC Celsius = -273.15 FreezingC Celsius =  0 BoilingC Celsius = 100 ) func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) } func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) / 5 * 9) }Copy the code

The package defines two named types — -Celsius and Fahrenheit, which correspond to two temperature measures. Even though they use the same underlying type float64, they are different types, so they cannot compare and merge using arithmetic expressions

Distinguishing these types prevents inadvertant merging of temperature values in different units of measurement. An explicit conversion is required to convert from FLOAT64 to Celsius or Fahrenheit. Celsius(t) and Fahrenheit(t) are type conversions, not function calls

For each type T, there is a corresponding type conversion operation T(x) that converts the type of the value x to type T. A type conversion is an expression that does not change the type value, only the type

The underlying type of a named type determines its structure and expressions, as well as the set of internal operations it supports, which are the same as if the underlying type were used directly. This means that the above types Celsius and Fahrenheit can use the same arithmetic operations as float64

fmt.Printf("%g\n", BoilingC - FreezingC) // 100 boilingF := CToF(BoilingC) fmt.Printf("%g\n", Boilingf-ctof (FreezingC)) // 180 fmt.Printf("%g\n", boilingf-freezingcCopy the code

Named types provide the conceptual convenience of avoiding writing complex types over and over again. The benefit is not obvious when the underlying type is a simple type such as Float64, but is much more obvious when it comes to structural types

reference

Go Programming Language — Alan A. A. Donovan

Go Language Learning Notes — Rain Marks