当前位置:网站首页>Another comparison operator related interview question let me understand that the foundation is very important

Another comparison operator related interview question let me understand that the foundation is very important

2020-11-09 19:11:00 New world grocery store

From the official account : New world grocery store

Comparison is not easy

Let's take a look at the results of the previous issue :

image

First , The author chose true, So the actual result is 41% Of the readers who chose the wrong answer . See the result , I believe Last article Still can help everybody .

After a lot of hard work, I finally understood what happened to the last interview question , At this time, I saw the interviewer smiling :“ What is the output below ”.

type blankSt struct {
    a int
    _ string
}
bst1 := blankSt{1, "333"}
bst2 := struct {
    a int
    _ string
}{1, "555"}
fmt.Println(bst1 == bst2)

Here I leave a suspense first , The results are shown later .

Type declaration

Be careful : This section does not introduce the basic content such as grammar , It mainly describes some nouns for the sake of understanding later .

The type declaration will identifier ( Type the name ) Bound to the type , The two forms are type definition and type alias .

Let's take an example of identifier type and defined type( This noun will be used later ) Explain :

//  Type the alias 
type t1 = struct{ x, y float64 }
//  The type definition 
type t2 struct{ x, y float64 }

identifier ( Type the name ): In the example above ,t1,t2 For identifier .

type struct{ x, y float64 } For the type .

Type aliases do not create new types . In the above example t1 and struct{ x, y float64 } It's the same type .

Type definitions create new types , And this new type is called defined type. In the above example , new type t2 and struct{ x, y float64 } It's a different type .

underlying type

A theorem
Every type T There is one. underlying type( I call it The original type , The original types in the following articles all represent underlying type).

Theorem 2 : If T It's predefined booleannumeric and string One type , Or type, literal quantity is T The primitive type of is itself , otherwise T The original type of T The original type of the type referenced in its type declaration .

Go In the array 、 Structure 、 The pointer 、 function 、interface{}、slice、map and channel Type is composed of type literal quantity . Let's say map For example :

type T map[int]string
var a map[int]string

In the example above ,T by map type ,a by map Variable of type , All of them are literal map[int]string And according to theorem 2, we know that T The original type of map[int]string.

Let's take another example to deepen our understanding of primitive types :

type (
    A1 = string
    A2 = A1
)

type (
    B1 string
    B2 B1
    B3 []B1
    B4 B3
)

In the above example ,stringA1A2B1 and B2 The original type of string[]B1B3 and B4 The original type of []B1.

The same type

stay Go In a defined type Types are always different from other types . The same type is as follows :

1、 If two arrays have the same length and the same element type, the two arrays are of the same type .

2、 If the element type of two slices is the same, then the two slices are of the same type .

3、 Two functions have the same number of arguments and the same number of return values , If the parameter type and return value type of the corresponding position are the same, the two function types are the same .

4、 If two pointers have the same basic type, they are of the same type .

5、 If two map Of the same type key And elements of the same type, these two map The same type .

6、 If two channel If they have the same element type and the same direction, the two channel The same type .

7、 If two structs have the same number of fields , And the corresponding field name is the same , If the type is the same and the label is the same, then the two structures are of the same type . For structures under different packages , As long as there are non exported fields, the two struct types are not the same .

8、 If the number and names of methods on both interfaces are equal , If methods with the same name have the same function type, the two interface types are the same .

Type is assignable

When any of the following conditions are satisfied , Variable x Can be assigned to the type of T The variable of .

1、x The type and T The same type .

2、x The type of V and T Having the same primitive type , also V and T At least one of them is not defined type.

type (
    m1 map[int]string
    m2 m1
)
var map1 map[int]string = make(map[int]string)
var map2 m1 = map1
fmt.Println(map2)

map1 and map2 The original type of the variable is map[int]string, And the satisfaction is only map2 yes defined type, So it can assign values normally .

var map3 m2 = map1
fmt.Println(map3)
var map4 m2 = map2

map3 and map1 The same conditions are met , So it can assign values normally . however map4 and map2 Not satisfied, at least one of them is not defined type This condition , Therefore, it will compile and report errors .

3、T yes interface{} also x The type of implements T All the ways .

4、x It's a two-way channel ,T It's the channel type ,x The type of V and T Having the same element type , also V and T At least one of them is not defined type.

According to the above, we can see that a hidden logic is , Two way channels can be assigned to one-way channels , But a one-way channel cannot be assigned to a two-way channel .


var c1 chan int = make(chan int)
var c2 chan<- int = c1
fmt.Println(c2 == c1) // true
c1 = c2 //  Compile error :cannot use c2 (variable of type chan<- int) as chan int value in assignment

because c1 It can be assigned to c2, So according to the theorem in the previous article “ In any comparison , At least one of the operands can be assigned to a variable of another type ” know c1 and c2 Comparable .

5、x Is a pre declared identifier nil,T Is a pointer 、 function 、 section 、map、channel or interface{} type .

6、x Can be by type T The value of is an untyped constant .

type (
    str1 string
    str2 str1
)
const s1 = "1111"
var s3 str1 = s1
var s4 str2 = s1
fmt.Println(s3, s4) // 1111 1111

In the above example ,s1 Is an untyped string constant, so s1 Can be assigned to the type of str1 and str2 The variable of .

The picture below is in vscode When the mouse hovers over a variable s1 When you give me a hint .

image

Be careful : In the actual verification process, the author found that some typed constants and variables will compile and report errors when assigning values .

const s2 string = "1111"
var s5 str1 = s2

The above code is in vscode The mistake in is cannot use s2 (constant "1111" of type string) as str1 value in variable declaration.

See the above compilation error , The author was shocked , Even if it doesn't satisfy the first 6 Point should also satisfy the first 2 Please . With the mood full of doubts, the author uses code jump , Last in builtin.go Found out type string string Such a sentence .

Combined with the above code, we know that str1 and string Is a new type created by a type definition, that is defined type, therefore var s5 str1 = s2 It's not satisfied with the first 2 spot .

builtin.go File pair booleannumeric and string All of the types are defined , Let's say int Take a step closer to verify :

type int1 int
var i1 int = 1
const i2 int = 1
var i3 int1 = i1 // cannot use i1 (variable of type int) as int1 value in variable declaration
var i4 int1 = i2 // cannot use i2 (constant 1 of type int) as int1 value in variable declaration

The above results are in line with expectations , Therefore, we should keep in mind the details of variable assignment in the usual development .

Analysis and summary

With the front The same type and Type is assignable Two sections of the basic knowledge, we follow the following steps to analyze and summarize the interview questions .

1、 Is the type the same ?

Let's list the two structures that need to be compared in the face-to-face questions :

type blankSt struct {
    a int
    _ string
}
struct {
    a int
    _ string
}

according to The same type The first section of a section 7 Know something about it , The two structures have the same number of fields , And the corresponding field name is the same 、 The same type and the same label , So the two structures are of the same type .

2、 Whether the assignment condition is satisfied ?

according to Type is assignable The first section of a section 1 Know something about it , The two structures are of the same type, so they satisfy the assignment condition .

The two structures in the interview question are relatively simple , The following is a supplement to different scenes of the structure .

  • Structure tag Different
type blankSt1 struct {
    a int `json:"a"`
    _ string
}
bst11 := struct {
    a int
    _ string
}{1, "555"}
var bst12 blankSt1 = bst11

The above code is in vscode The error reported in is cannot use bst11 (variable of type struct{a int; _ string}) as blankSt1 value in variable declaration. Two structures as long as tag If they are different, the types of these two structures are different , In this case, the two structures do not satisfy any assignment condition .

  • Structures in different packages , And all fields are exported
package ttt

type ST1 = struct {
    F string
}
var A = ST1{
    F: "1111",
}

package main

type st1 struct {
    F string
}

var st11 st1 = ttt.A
fmt.Println(st11) // output: {1111}

according to The same type The first section of a section 7 Point and Type is assignable The first section of a section 1 Know something about it ,ST1 and st1 Same type and assignable , So the above code works well

  • Structures in different packages , And contains fields that are not exported
package ttt
type ST2 = struct {
    F string
    a string
}
var B = ST2{
    F: "1111",
}
package main
type st2 struct {
    F string
    a string
}
var st21 st2 = ttt.B
fmt.Println(st21)

When running the above code cannot use ttt.B (type struct { F string; ttt.a string }) as type st2 in assignment error .

because st2 and ST2 The types are different and their original types are struct { F string a string } and struct { F string; ttt.a string }, therefore ttt.b Cannot assign to st21.

3、 summary

blankSt and struct { a int _ string } The type is the same and satisfies the assignment condition , Therefore, according to “ In any comparison , At least one of the operands can be assigned to a variable of another type ” This must understand the question in the interview bst1 and bst2 Comparable .

Next, according to the structure comparison rules mentioned in the last article bst1 and bst2 equal , So the final output of the interview question is true.

If it wasn't for reading another one Go Basic grammar of , I don't know that so many details have been left out .“ Read a hundred times, and you will see it ”, The ancients did not deceive me !

Last , I sincerely hope that this paper can be helpful to readers .

notes :

  1. When writing this article , The author uses go Version is : go1.14.2
  2. The complete example used in the article :https://github.com/Isites/go-...

版权声明
本文为[New world grocery store]所创,转载请带上原文链接,感谢