当前位置:网站首页>Go Interviewer: can go structures be compared and why?

Go Interviewer: can go structures be compared and why?

2021-06-21 23:04:12 Fried fish eddycjy

WeChat search 【 I have fried fish in my head 】 Pay attention to this fried fish with fried liver . this paper GitHub github.com/eddycjy/blo… Included , There's my series 、 Information and open source Go The book .

Hello everyone , I'm fried fish .

Recently, gold, silver and four , It's the season for interviews . In my Go There are many small partners in the reader exchange group discussing some of the problems they encountered in the interview process Go Interview questions .

Today's hero , yes Go Required skills for Engineers , It's also very easy to step on the pit , Namely “Go Interview questions :Go Structure (struct) Can we compare ?

If you can compare , What is it for? ? If it can't be compared , And why ?

Please recite the answers in your mind here , Let's discuss it with fried fish Go The philosophy of Technology .

What is the structure

stay Go There is a basic type of language , Developers call it a structure (struct). yes Go Very common in language , The basic definition :

type struct_variable_type struct {
    member definition
    member definition
    ...
    member definition
}
 Copy code 

A simple example :

package main

import "fmt"

type Vertex struct {
    Name1 string
    Name2 string
}

func main() {
    v := Vertex{" It's in my head ", " Fried fish "}
    v.Name2 = " Steamed fish "
    fmt.Println(v.Name2)
}
 Copy code 

Output results :

 Steamed fish 
 Copy code 

This part belongs to basic knowledge , So don't explain too much . If you don't understand , It is suggested that we study again Go Fundamentals of language grammar .

Compare two

Example a

Next, we will start the discussion Go The problem of structure comparison , The first example is as follows :

type Value struct {
    Name   string
    Gender string
}

func main() {
    v1 := Value{Name: " Fried fish ", Gender: " male "}
    v2 := Value{Name: " Fried fish ", Gender: " male "}
    if v1 == v2 {
        fmt.Println(" I have fried fish in my head ")
        return
    }

    fmt.Println(" I don't have fried fish in my head ")
}
 Copy code 

We declared two variables , Namely v1 and v2. All of them are Value Instantiation of structure , It's two instances of the same structure .

What is the result of their comparison , It's output ” I have fried fish in my head “, still ” I don't have fried fish in my head “?

Output results :

 I have fried fish in my head 
 Copy code 

The final output is ” I have fried fish in my head “, The preliminary conclusion can be compared among different structures . All's well that ends well , Is this article coming to an end ?

Of course not. ... A lot of people will step on this Go The pit of language , The truth is that the structure is comparable , It's not comparable , Don't go astray , This is a very " Interesting " The phenomenon of .

Example 2

Let's continue with the above example , We added a pointer type reference to the original structure .

The second example is as follows :

type Value struct {
    Name   string
    Gender *string
}

func main() {
    v1 := Value{Name: " Fried fish ", Gender: new(string)}
    v2 := Value{Name: " Fried fish ", Gender: new(string)}
    if v1 == v2 {
        fmt.Println(" I have fried fish in my head ")
        return
    }

    fmt.Println(" I don't have fried fish in my head ")
}
 Copy code 

What is the output of this program , Let's guess , Variables are still two instances of the same structure , Values are assigned in the same way and in the same way , Whether it should output “ I have fried fish in my head ”?

The answer is : I don't have fried fish in my head .

Example 3

We continue not to believe in evil , Try another basic type , See if the results are equal .

The third example is as follows :

type Value struct {
    Name   string
    GoodAt []string
}

func main() {
    v1 := Value{Name: " Fried fish ", GoodAt: []string{" Fried ", " Fried ", " steamed "}}
    v2 := Value{Name: " Fried fish ", GoodAt: []string{" Fried ", " Fried ", " steamed "}}
    if v1 == v2 {
        fmt.Println(" I have fried fish in my head ")
        return
    }

    fmt.Println(" I don't have fried fish in my head ")
}
 Copy code 

What is the output of this program ?

The answer is :

# command-line-arguments
./main.go:15:8: invalid operation: v1 == v2 (struct containing []string cannot be compared)
 Copy code 

When the program is running, it will report an error directly ,IDE It's also an error , Not a single fried fish can be exported .

Example four

The different structures , The same value content , Can we make a comparison ?

Fourth example :

type Value1 struct {
    Name string
}

type Value2 struct {
    Name string
}

func main() {
    v1 := Value1{Name: " Fried fish "}
    v2 := Value2{Name: " Fried fish "}
    if v1 == v2 {
        fmt.Println(" I have fried fish in my head ")
        return
    }

    fmt.Println(" I don't have fried fish in my head ")
}
 Copy code 

obviously , Will report an error directly :

# command-line-arguments
./main.go:18:8: invalid operation: v1 == v2 (mismatched types Value1 and Value2)
 Copy code 

Is it impossible to compare ? Does not , We can do it with casts :

	if v1 == Value1(v2) {
		fmt.Println(" I have fried fish in my head ")
		return
	}
 Copy code 

So the program will work properly , And output “ I have fried fish in my head ”. Of course , If it's a non comparable type , Still not .

Why?

Why? Go The comparison of some structures is normal , Some can't , And even a direct error . Is there anything “ Hidden rules ” Do you ?

stay Go In language ,Go Sometimes structures can't be compared directly , When its basic type contains :slice、map、function when , It can't be compared . If forced to compare , This will lead to the direct error reporting in the example .

And the pointer reference , Although they are all new(string), From the appearance, it's a thing , But the specific return address is different .

So to compare , It needs to be changed to :

func main() {
    gender := new(string)
    v1 := Value{Name: " Fried fish ", Gender: gender}
    v2 := Value{Name: " Fried fish ", Gender: gender}
    ...
}
 Copy code 

In this way, we can ensure the comparison between the two . If we are forced to be helpless , It is required to compare with structure ?

In this case, we can use the reflection method reflect.DeepEqual, as follows :

func main() {
    v1 := Value{Name: " Fried fish ", GoodAt: []string{" Fried ", " Fried ", " steamed "}}
    v2 := Value{Name: " Fried fish ", GoodAt: []string{" Fried ", " Fried ", " steamed "}}
    if reflect.DeepEqual(v1, v2) {
        fmt.Println(" I have fried fish in my head ")
        return
    }

    fmt.Println(" I don't have fried fish in my head ")
}
 Copy code 

So that we can compare them correctly , The output is “ I have fried fish in my head ”.

The reflection comparison method used in the example reflect.DeepEqual It is often used to determine whether two values have the same depth , The rules are as follows :

  • Values of the same type are of equal depth , Different types of values never have the same depth .
  • When array values (array) When the depth of corresponding elements is equal , Array values are of equal depth .
  • When the structure (struct) Value if its corresponding field ( Including exported and not exported fields ) It's all the same depth , Then the value is equal in depth .
  • Function as (func) If the values are all zero , The depth is equal ; Otherwise, it's not the same depth .
  • When the interface (interface) If you hold a specific value with the same depth , Then the depth is equal .
  • ...

More specifically, you can go to golang.org/pkg/reflect/#DeepEqual Take a detailed look :

reflect.DeepEqual  Complete description

The method is right Go All types in the language are compatible and discriminated , Because this is not the point of this article , So we don't go any further .

summary

In this paper , We aim at Go The structure of language (struct) Whether it can be compared is expanded and explained by specific examples .

It's essentially right Go Understanding the basic data types of language , It can be regarded as the concrete further development of deformation into the structure .

I don't know if you are Go What has the structure suffered , Welcome to leave a message in the comment area below to share and discuss with us .

If you have any questions, you are welcome to feedback and exchange in the comments area , The best relationship is mutual achievement , Everyone give the thumbs-up Namely Fried fish The greatest power of creation , Thank you for your support .

Articles are constantly updated , You can search through wechat 【 I have fried fish in my head 】 read , reply 【000】 Have I prepared the first-line factory interview algorithm solution and information ; this paper GitHub github.com/eddycjy/blo… Included , welcome Star Hurry up .

版权声明
本文为[Fried fish eddycjy]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/06/20210601175233465b.html