Exploring Structs in GO
Published: 2023-09-16 10:23:33

In Go , a Struct is a composite data type that groups together zero or more value of different types under a single unit.It is similar to a class in object-oriented programming but with some differences.

## Defining a Struct In GO:

To define a Struct in GO, you use a `type` keyword followed by the name of struct .Here’s an example :

```
type person struct {
Name string
Age int
Address Address
}
```
in this example , we define a struct called `person` with three fields: `Name` ,`Age`and `Address` .The `Address` field is a type of `Address` , which is another struct that we discuss later.

**Initializing a struct:**
First, you create an instance of a struct, then you simply provide values for its fields during initialization.Here’s an example:

```
p := person {
Name : "Umer",
Age : 18,
Address : Address {
City : "Islamabad",
State : "Capital",
    },
}
```
**Accessing and Modifying Fields of a Struct:**
To access the fields of a struct in Go, you use the dot notation. we can access the fields of a `person` srtruct using dot dot notation.For example we print the name of the `person` , we can use following code :

```
fmt.Println(p.Name)

The Output Is "Umer"

//Modify Age field
p.Age = 20
fmt.Println(p.Age)

The ouput is 20
```
**Nested Structs in Go:**
As we saw earlier, we can define a struct as a field of another struct. This is known as nested structs in Go. Here’s an example:

```
type Address struct {
    Street string
    City   string
    State  string
}

type Person struct {
    Name    string
    Age     int
    Address Address
}
```
In this example, we define a struct called `Address` with three fields: `Street`, `City`, and `State`. We then define a struct called `Person` with three fields: `Name`, `Age`, and `Address`. The `Address` field is of type `Address`, which is the nested struct we discuss earlier.
**Defining Methods on a Struct in Go:**
**Value Receiver:**
In Go , you can also define methods on a struct. A method is like a function that needs a receiver to get invoked. To define a method we need a function with a receiver .Value receiver work on copy of the orignal data.so, you can't modify the fields of struct.when you modify the fields of struct you get a compile-time error .Here’s an example:

```
type Rectangle struct {
    Width  float64
    Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}
```
In this example, we define a struct called `Rectangle` with two fields: `Width` and `Height`. We then define a method called `Area` that calculates the area of the `rectangle`. The method has a receiver of type `Rectangle`, which can work on any variable of type `Rectangle`.
so, we can create instance of type `rectangle` and invoke `Area()` method on it.

```
r := rectangle{Width : 10, Height : 5}
fmt.Println(r.Area())

//OutPut is "50".
So, we work on the copy of orignal data . 
we can't modify the fields of type `rectangle`.
```
**Pointer receiver (Pass by Reference):**
In Go, A method with a `*pointer` receiver operates directly on the orignal struct data.It’s like working with orignal struct, not a copy.Here’s an example:

```
type person struct {
Age int
}
//Method with a pointer receiver 
func (p *person) modify() int {
p.Age++
return p.Age
}
//Create instances of person and invoke method

func main() {
p := &person{Age :18}
p.modify()
fmt.Println(p.Age)
```
The output is `19` instead of `18` ,because it working on a orignal struct, not a copy.

**Embedding Structs in Go:**
In Go, When you embed the `inner` struct within an outer `struct` , the fields of `inner` structs and method are becomes part of `outer` struct.
_'has-a' relationship:_
> "Embedding a struct in another struct establishes a 'has-a' relationship between them, where the containing struct possesses or includes the embedded struct as one of its components."
Here’s an example :

```
type Inner struct {
    Id int
    Address string
}

type Outer struct {
    Name string
    Age  int
    Inner   //Inner struct embed in outer struct
}
```
**Initializing:**
```
embed := Outer {
Name : "Umer",
Age : 18,
Inner : Inner {
Id : 5633,
Address : "Islamabad",
      },
 }

fmt.Println(embed.Id)// output is 5633
fmt.Println(embed.Address)// output is "Islamabad".
```
so, `outer` struct can direct access the fields and methods of an `Inner` struct.

**“Field Name Conflicts in Nested Structs”:**
When `Inner` and `Outer` structs have fields with same name, and the `Inner` struct is embedded within the `outer` struct, the `inner` field will `“shadow”` the `outer` field.Here’s an example :
```
type Outer struct {
    Field int
    InnerStruct
}

type InnerStruct struct {
    Field int
}
//Initializing fields

 obj := Outer{
        Field: 1,
        InnerStruct: InnerStruct{
            Field: 2,
        },
    }

  fmt.Println(obj.Field) // Accesses the outer Field, prints 1
  fmt.Println(obj.InnerStruct.Field) // Accesses the inner Field, prints 2
```
In this example, there are two fields named `Field` in the outer and inner structs. When you access `obj.Field`, it refers to the outer field, and when you access `obj.InnerStruct.Field`, it refers to the inner field. The inner field takes precedence within the scope of the outer struct.

**_It’s crucial to remember that “ Embedding Is Not Inheritance”._**


   

## Feel free to leave any comment here.