Contents
Outline
In this blog post, I will show you how to use Struct
to define variables and how to use it in Golang. You can see the full source code of this blog post on the link below.
Struct
In Golang, the struct is a type that binds various type of fields together.
Struct role
The struct makes code coupling and dependency low and cohesion high.
Low coupling, high cohesion
Function
binds related code blocks, so it makes cohesion high and better reusability.Array
binds same type data, so it makes cohension high.Struct
bind related data, so it makes cohesion high and better reusability.
This struct becomes the base of OOP(Object Oriented Programming).
Define struct
In Golang, you can define the struct like the below.
type TYPE_NAME struct {
Field_NAME TYPE
...
Field_NAME TYPE
}
You can use the field name to make the public field or private field like Function. If the field name starts with an uppercase letter, it can be used as public field. If it starts wit a lowercase letter, it can be used as private field.
To check this, create the main.go
file and modify it like the below.
package main
import "fmt"
type Student struct {
Name string
Class int
No int
}
func main() {
var s Student
s.Name = "Tom"
s.Class = 1
s.No = 1
fmt.Println(s)
fmt.Printf("%v\n", s)
fmt.Printf("Name: %s, Class: %d, No: %d\n", s.Name, s.Class, s.No)
}
When you execute the program, you can see the following result.
# go run main.go
{Tom 1 1}
{Tom 1 1}
Name: Tom, Class: 1, No: 1
Initialization
If you define a struct variable without initialization, all fields will be assigned the default value of the type.
type Student struct {
Name string
Class int
No int
}
var s Student;
When you define the struct variable, you can assign intial values in field order like the below.
var s1 Student = Student{"Tom", 1, 2}
var s2 Student = Student{
"John",
1,
3,
}
Also, you can assign the initial values with field names like the below.
var a Student = Student{ Name: "Deku", Class: 1, No: 3 };
To check these, modify the main.go
file like the below.
package main
import "fmt"
type Student struct {
Name string
Class int
No int
}
func main() {
var s Student
fmt.Println(s)
var s1 Student = Student{"Tom", 1, 2}
var s2 Student = Student{
"John",
1,
3,
}
fmt.Println(s1)
fmt.Println(s2)
var s3 Student = Student{Name: "Deku", Class: 1, No: 3}
fmt.Println(s3)
}
When you execute the code above, you can see the following result.
# go run main.go
{ 0 0}
{Tom 1 2}
{John 1 3}
{Deku 1 3}
Nested struct
In Golang, Struct can inlcude other structs. This is called Nested struct
in Golang.
type ClassInfo struct {
Class int
No int
}
type Student struct {
Class ClassInfo
Name string
}
You can initialize the nested struct like the below.
var s Student = Student{
Class: ClassInfo{Class: 1, No: 1},
Name: "John",
}
To check this, modify the main.go
file.
package main
import "fmt"
type ClassInfo struct {
Class int
No int
}
type Student struct {
Class ClassInfo
Name string
}
func main() {
var s Student = Student{
Class: ClassInfo{Class: 1, No: 1},
Name: "John",
}
fmt.Println(s.Class.Class)
fmt.Println(s.Class.No)
fmt.Println(s.Name)
}
When you execute the code, you can see the following result.
# go run main.go
1
1
John
Embedded field
In Golang, Struct can include other structs, and you can omit the field names. This is called Embedded field
in Golang.
type ClassInfo struct {
Class int
No int
}
type Student struct {
ClassInfo
Name string
}
You can initialize the embedded field
like the below.
var s Student = Student{
ClassInfo: ClassInfo{Class: 1, No: 1},
Name: "John",
}
And, you can directly acceess the embedded field
to use it like the below.
fmt.Println(s.Class)
fmt.Println(s.No)
fmt.Println(s.Name)
Also, you can define the duplicated field name with embedded field
.
type ClassInfo struct {
Class int
No int
}
type Student struct {
ClassInfo
Name string
No int
}
In this case, you can initialize it like the below.
var s1 DupStudent = DupStudent{
ClassInfo: ClassInfo{Class: 1, No: 1},
Name: "John",
No: 10,
}
The field name is duplicated, so when you access the field directly, the value of the current struct variable is returned.
fmt.Println(s1.No) // 10
Therefore, if you want to access the value of the embedded field
, you can access it like the below.
fmt.Println(s1.ClassInfo.No) // 1
To check these, modify the main.go
file.
package main
import "fmt"
type ClassInfo struct {
Class int
No int
}
type Student struct {
ClassInfo
Name string
}
type DupStudent struct {
ClassInfo
Name string
No int
}
func main() {
var s Student = Student{
ClassInfo: ClassInfo{Class: 1, No: 1},
Name: "John",
}
fmt.Println(s.Class)
fmt.Println(s.No)
fmt.Println(s.Name)
var s1 DupStudent = DupStudent{
ClassInfo: ClassInfo{Class: 1, No: 1},
Name: "John",
No: 10,
}
fmt.Println(s1.Class)
fmt.Println(s1.No)
fmt.Println(s1.Name)
fmt.Println(s1.ClassInfo.No)
}
When you execute the code after modifying, you can see the following result.
# go run main.go
1
1
John
1
10
John
1
Memory alignment
When you write the code in Golang, maybe you don’t need to care about the memory. But, if you write the code for the small device or for memory efficiency, you need to know Memory alignment
.
s := Student{"John", 1}
var str string = "John"
var i int = 1
fmt.Println(unsafe.Sizeof(s))
fmt.Println(unsafe.Sizeof(str))
fmt.Println(unsafe.Sizeof(i))
To make the CPU calculate easily, Golang stores the Struct in memory in multiples of 8 bytes.
24
16
8
So, if the field type is smaller than 8 bytes, Golang adds empty spaces(Memory Padding
) to make it multiples of 8 bytes.
type Memory struct {
A int8 // 1 byte
B int // 8 bytes
C int8 // 1 byte
D int // 8 bytes
E int8 // 1 byte
// 19 bytes
}
Like above, if we think about the memories of the typs, it will be 19 bytes. However, Struct will be stored in multiples 8 bytes, so Golang adds the empty spaces to A, C, E variables to amke them 8 bytes. So, the real memory size is 40 bytes.
To avoid the wasted memory by empty spaces(Memory Padding), you can do memory alignment by declaring a small memory first as the follows.
type Memory struct {
A int8 // 1 byte
C int8 // 1 byte
E int8 // 1 byte
B int // 8 bytes
D int // 8 bytes
// 19 bytes
}
This struct also uses 19 bytes, but A, C, E are defined first. So, these variables use 3 bytes, and then Golang adds 5 empty spaces to make it 8 bytes. So, the 20 bytes mermory is used to store this struct.
Like this, Golang stores the Struct in multiples of 8 bytes to make the CPU calculate easily. So, if you don’t waste the memory, you should think about the memory alignment.
To check these, open the main.go
file and modify it like the below.
package main
import (
"fmt"
"unsafe"
)
type Student struct {
Name string
Class int
}
type Memory struct {
A int8
B int
C int8
D int
E int8
}
type MemoryAlignment struct {
A int8
C int8
E int8
B int
D int
}
func main() {
s := Student{"John", 1}
var str string = "John"
var i int = 1
fmt.Println(unsafe.Sizeof(s))
fmt.Println(unsafe.Sizeof(str))
fmt.Println(unsafe.Sizeof(i))
m := Memory{1, 2, 3, 4, 5}
fmt.Println(unsafe.Sizeof(m))
ma := MemoryAlignment{1, 2, 3, 4, 5}
fmt.Println(unsafe.Sizeof(ma))
}
When you execute the code, you can get the result like the below.
# go run main.go
24
16
8
40
24
Completed
Done! we’ve seen how to define the Struct and how to use it. Also, we’ve seen the Struct memory usages, and how to use Memory Alignment to use the memory more efficiently.
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku
.Deku
created the applications with Flutter.If you have interested, please try to download them for free.