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