2.2 ساختار (struct)

2.2 ساختار (struct)

در زبان گو ساختار کالکشنی از فیلدها با تایپ‌های مختلف است. شما با استفاده از ساختار می‌توانید یک مدل کلی از بدنه پروژه خود را تعریف کنید. برای نمونه ما در مثال زیر یک نمونه از ساختار employee کارمند را مثال زدیم تا شما کمی با مفهوم ساختار آشنا شوید.

1type employee struct {
2    name   string
3    age    int
4    salary int
5}

نکته: ساختار می‌تواند بصورت خالی جهت برخی اهداف ایجاد گردد. به مثال زیر دقت کنید:‌

1type sample struct {}

اگر می‌خواهید در مورد متودها اطلاعات کسب کنید به بخش متدها روی ساختار سر بزنید، هر چند توصیه می‌کنم اول این قسمت رو بخونید و تمرین کنید و بعد به قسمت متودها بروید.

  • برای ایجاد ساختار باید از کلمه کلیدی type اسم ساختار و در ادامه کلمه کلیدی struct استفاده کنید.

  • سپس داخل بدنه ساختار فیلدها را تعریف کنید.

    • فیلد name از نوع string
    • فیلد age از نوع int
    • فیلد salary از نوع int
ساختار را در زبان گو، با class در سایر زبان‌ها مقایسه می‌کنند. هرچند زبان گو یک زبان شی‌گرا محسوب نمی‌شود.

2.2.1 تعریف تایپ struct #

به مثال زیر توجه کنید:

1type point struct {
2    x float64
3    y float64
4}

در مثال بالا ما ۲ تا فیلد برای ساختار تعریف کردیم که هر دو فیلد از نوع float64 هستند.

2.2.2 ایجاد یک متغیر ساختار (struct) #

برای ایجاد یک متغیر ساختار می‌توانید یک متغیر تعریف کنید و ساختار را به عنوان مقدار به آن بدهید. به مثال زیر توجه کنید:

1emp := employee{}

در مثال بالا ما یک متغیر با مقدار پیش‌فرض صفر ساختار employee تعریف کردیم.

زمانیکه یک متغیر ساختار خالی، مانند مثال بالا تعریف می‌کنید مقدار استفاده شده از حافظه 0 بایت است.
  • ایجاد متغیر ساختار و مقدار دهی فیلدها در یک خط:
1emp := employee{name: "Sam", age: 31, salary: 2000}
  • ایجاد متغیر ساختار و مقدار دهی فیلد در خط‌های مختلف (این روش برای خوانایی و درک بهتر توصیه می‌شود) :
1emp := employee{
2   name:   "Sam",
3   age:    31,
4   salary: 2000,
5}

توجه کنید هیچ اجباری نیست که حتماً شما باید فیلدی را مقدار دهی کنید، شما می‌توانید هر زمانیکه نیاز داشتید ساختار خودتان رو مقدار دهی کنید.

1emp := employee{
2   name: "Sam",
3   age: 31,
4}

در مثال بالا ما فیلد salary را مقدار دهی نکردیم. کامپایلر بطور پیش‌فرض با توجه به تایپ فیلد، مقدار پیش‌فرض صفر را برای اون تایپ در نظر می‌گیرد. در ادامه به مثالی که از نحوه ایجاد ساختارها زدیم، توجه کنید:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp1 := employee{}
13    fmt.Printf("Emp1: %+v\n", emp1)
14
15    emp2 := employee{name: "Sam", age: 31, salary: 2000}
16    fmt.Printf("Emp2: %+v\n", emp2)
17
18    emp3 := employee{
19        name:   "Sam",
20        age:    31,
21        salary: 2000,
22    }
23    fmt.Printf("Emp3: %+v\n", emp3)
24
25    emp4 := employee{
26        name: "Sam",
27        age:  31,
28    }
29    fmt.Printf("Emp4: %+v\n", emp4)
30}
1$ go run main.go
2Emp1: {name: age:0 salary:0}
3Emp2: {name:Sam age:31 salary:2000}
4Emp3: {name:Sam age:31 salary:2000}
5Emp4: {name:Sam age:31 salary:0}
  • ایجاد متغیر ساختار و مقدار دهی فیلدها بدون نام فیلد:

شما می‌توانید فیلدها را بدون اینکه نام فیلد را قرار دهید مقدار دهی کنید اما از نظر تکنیکی این کار توصیه نمی‌شود، دلیل این توصیه هم این است که اگر شما فیلدها رو به این روش مقدار دهی کنید، باید ترتیب رو در نظر بگیرید یعنی 1: باید نام باشد، 2: باید سن باشد، 3: باید درآمد باشد و اگر این ترتیب رعایت نشود شما دیتای اشتباهی خواهید داشت.

1emp := employee{"Sam", 31, 2000}
2
3{Sam 31 2000} // حروجی

در مثال بالا ترتیب رعایت شده. به مثال زیر توجه کنید:

1emp := employee{"Sam", 2000, 31}
2
3{Sam 2000 31} // حروجی

همانطور که در مثال بالا دیدین الان با ترتیب اشتباه سن کارمند و درآمدش جابه جا شدن و ما دیتای اشتباهی از کارمند خواهیم داشت.

2.2.3 دسترسی و تنظیم فیلدهای ساختار (struct) #

زمانیکه شما یک متغیر ساختار تعریف می‌کنید، می‌توانید خیلی آسان با استفاده از همان متغیر به فیلدهای ساختار دسترسی پیدا کنید و مقدار هر کدام از فیلدها را تغییر دهید. به مثال زیر توجه کنید:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp := employee{name: "Sam", age: 31, salary: 2000}
13
14    //Accessing a struct field
15    fmt.Printf("Current name is: %s\n", emp.name)
16
17    //Assigning a new value to name field
18    emp.name = "John"
19    fmt.Printf("New name is: %s\n", emp.name)
20}
1$ go run main.go
2Current name is: Sam
3New name is: John

2.2.4 کار با اشاره‌گر (Pointer) در ساختار (struct) #

شما برای ایجاد یک struct از نوع اشاره‌گر می‌توانید از دو حالت زیر استفاده کنید:

  • با استفاده از عملگر & که اشاره به خانه حافظه دارد
  • با استفاده از تابع new

2.2.4.1 ایجاد ساختار با استفاده از عملگر & #

برای اینکه بتوانید یک ساختار از نوع اشاره گر ایجاد کنید می‌توانید از عملگر & استفاده کنید. به مثال زیر توجه کنید:

1emp := employee{name: "Sam", age: 31, salary: 2000}
2empP := &emp

حتی شما می‌توانید یک ساختار اشاره‌گر را مستقیماً ایجاد کنید این روش پیشنهاد می‌شود. به مثال زیر توجه کنید:

1empP := &employee{name: "Sam", age: 31, salary: 2000}

در مثال زیر هر دو روش رو برای شما توضیح دادیم. با دقت به کد و خروجی کد نگاه کنید:‌

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp := employee{name: "Sam", age: 31, salary: 2000}
13    empP := &emp
14    fmt.Printf("Emp: %+v\n", empP)
15    empP = &employee{name: "John", age: 30, salary: 3000}
16    fmt.Printf("Emp: %+v\n", empP)
17}
1$ go run main.go
2Emp: &{name:Sam age:31 salary:2000}
3Emp: &{name:John age:30 salary:3000}

2.2.4.2 ایجاد ساختار با استفاده تابع new #

1func new(Type) *Type

همینطور که در تعریف تابع new هم می‌بینید، این تابع یک تایپ از ما می‌گیرد و مقدار دهی می‌کند، و در آخر هم تایپ را از نوع اشاره‌گر برای ما بر می‌گرداند.

با استفاده از تابع new :

  • شما یک ساختار ایجاد می‌کنید.
  • سپس فیلدها، با مقدار پیش‌فرض صفر مقدار دهی اولیه می‌شوند.
  • در نهایت ساختار شما از نوع اشاره‌گر بازگشت داده می‌شود.

به مثال زیر توجه کنید:

1empP := new(employee)

برای اینکه آدرس خانه حافظه ساختار، از نوع اشاره‌گر را ببینید کافی است با استفاده از p% اون ساختار رو چاپ کنید. به مثال زیر توجه کنید:

1fmt.Printf("Emp Pointer: %p\n", empP)

برای اینکه مقدار کلی فیلدها را ببینید کافی است با استفاده از v+% اون رو چاپ کنید. به مثال زیر توجه کنید:

1fmt.Printf("Emp Value: %+v\n", *empP)

در مثال زیر خروجی آنچه در بالا گفته شد رو قرار دادیم. لطفاً با دقت به مثال زیر نگاه کنید و در آخر هم مثال‌های مشابهی رو برای خودتان بنویسید:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    empP := new(employee)
13    fmt.Printf("Emp Pointer Address: %p\n", empP)
14    fmt.Printf("Emp Pointer: %+v\n", empP)
15    fmt.Printf("Emp Value: %+v\n", *empP)
16}
1$ go run main.go
2Emp Pointer Address: 0xc000130000
3Emp Pointer: &{name: age:0 salary:0}
4Emp Value: {name: age:0 salary:0}

2.2.5 چاپ یک متغیر ساختار (struct) #

برای اینکه بتوانید یک متغیر ساختار struct را چاپ کنید، از دو روش زیر می‌توانید استفاده کنید. توجه کنید متغیر ساختار بصورت key/value هست.

  • با استفاده از پکیج fmt
  • با استفاده از پکیج json/encoding

2.2.5.1 چاپ با استفاده از fmt #

در پکیج fmt ما 2 تا تابع کاربردی جهت چاپ داریم که اکثر اوقات از این دو تابع استفاده می‌کنیم:

  • تابع Println ورودی را با فرمت پیش‌فرض چاپ می‌کند.
  • تابع Printf ورودی را با فرمت مشخص شده چاپ می‌کند فرمت رو خود ما مشخص می‌کنیم.

در مثال زیر ما یک نمونه از ساختار employee را ایجاد کردیم:

1emp := employee{name: "Sam", age: 31, salary: 2000}

حال با استفاده از تابع Printf ساختار را با فرمت دلخواه خودمان چاپ کردیم:

1fmt.Printf("%v", emp)  -  {Sam 31 2000}
1fmt.Printf("%+v", emp) - {name:Sam age:31 salary:2000}
  • %v - مقدار value هر کدام از فیلدهای ساختار را چاپ می‌کند.
  • %+v - مقدار هرکدام از فیلدها به همراه اسم فیلد key-value را چاپ می‌کند.

در مثال زیر ما با استفاده از از تابع Println ساختار را چاپ کردیم:

1fmt.Println(emp) - {Sam 31 2000}

در نهایت کد زیر یک مثال کلی از چاپ با استفاده از پکیج fmt است‌:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp := employee{name: "Sam", age: 31, salary: 2000}
13    fmt.Printf("Emp: %v\n", emp)
14    fmt.Printf("Emp: %+v\n", emp)
15    fmt.Printf("Emp: %#v\n", emp)
16    fmt.Println(emp)
17}
1$ go run main.go
2Emp: {Sam 31 2000}
3Emp: {name:Sam age:31 salary:2000}
4Emp: main.employee{name:"Sam", age:31, salary:2000}
5{Sam 31 2000}

2.2.5.2 چاپ ساختار با استفاده از پکیج JSON #

در این روش ما با استفاده از ۲ تابع Marshal و MarshalIndent پکیج json، ساختار را encode می‌کنیم و در نهایت خروجی encode شده را چاپ می‌کنیم.

  • Marshal - در این تابع ما به عنوان ورودی‌، ساختار را پاس می‌دهیم و در نهایت ۲ خروجی از نوع بایت و خطا دریافت می‌کنیم.
1Marshal(v interface{}) ([]byte, error)
  • MarhsalIndent - در این تابع ما ۳ تا ورودی به تابع می‌فرستیم, به ترتیب ساختار، پیشوند و indent و در نهایت ۲ خروجی از نوع بایت و خطا دریافت می‌کنیم.
1MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

حالا با استفاده از توابع فوق یک کد نمونه مثال می‌زنیم و به شما یاد می‌دیم که چطور از این توابع استفاده کنید. به مثال زیر دقت کنید:

 1package main
 2
 3import (
 4    "encoding/json"
 5    "fmt"
 6    "log"
 7)
 8
 9type employee struct {
10    Name   string
11    Age    int
12    salary int
13}
14
15func main() {
16    emp := employee{Name: "Sam", Age: 31, salary: 2000}
17    //Marshal
18    empJSON, err := json.Marshal(emp)
19    if err != nil {
20        log.Fatalf(err.Error())
21    }
22    fmt.Printf("Marshal funnction output %s\n", string(empJSON))
23
24    //MarshalIndent
25    empJSON, err = json.MarshalIndent(emp, "", "  ")
26    if err != nil {
27        log.Fatalf(err.Error())
28    }
29    fmt.Printf("MarshalIndent funnction output %s\n", string(empJSON))
30}
1$ go run main.go
2Marshal funnction output {"Name":"Sam","Age":31}
3
4MarshalIndent funnction output {
5  "Name": "Sam",
6  "Age": 31
7}
برای اطلاعات بیشتر در خصوص پکیج json می‌توانید به بخش آموزش کار با json مراجعه کنید.

2.2.6 کار با تگ ها در ساختار (struct) #

ساختار زبان گو، به شما امکان اضافه کردن metadata به هر یک از فیلدها را می‌دهد و ما این قابلیت را به عنوان تگ می‌شناسیم. تگ‌ها برای انجام یکسری عملیات خاص نظیر encode/decode، اعتبارسنجی مقادیر فیلدها و … به ما کمک می‌کند و یکی از کاربردی‌ترین عناوین در ساختار هستند.

به مثال های زیر توجه کنید تا کارکرد تگ ها را متوجه شوید:

1type strutName struct{
2   fieldName type `key:"value" key2:"value2"`
3}
1type employee struct {
2    Name   string
3    Age    int 
4    Salary int 
5}

در این مثال، مقدار داخل متغیری که از نوع Employee است را تبدیل به json می کنیم و چاپ می کنیم.

 1package main
 2
 3import (
 4    "encoding/json"
 5    "fmt"
 6    "log"
 7)
 8
 9type employee struct {
10    Name   string
11    Age    int
12    Salary int
13}
14
15func main() {
16    emp := employee{Name: "Sam", Age: 31, Salary: 2000}
17    //Converting to jsonn
18    empJSON, err := json.MarshalIndent(emp, "", "  ")
19    if err != nil {
20        log.Fatalf(err.Error())
21    }
22    fmt.Println(string(empJSON))
23}

خروجی :

1$ go run main.go
2{
3  "Name": "Sam",
4  "Age": 31,
5  "Salary": 2000
6}

حالا به ما می گویند که اول اسم فیلد ها در خروجی json با حرف بزرگ شروع نشود و حرف کوچک باشد. اولین چیزی که شاید به ذهن شما خطور کند این است که اسم فیلد ها را در ساختار تعریف شده با حروف کوچک شروع کنیم:

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"log"
 7)
 8
 9type employee struct {
10	name   string
11	age    int
12	salary int
13}
14
15func main() {
16	emp := employee{name: "Sam", age: 31, salary: 2000}
17	//Converting to jsonn
18	empJSON, err := json.MarshalIndent(emp, "", "   ")
19	if err != nil {
20		log.Fatalf(err.Error())
21	}
22	fmt.Println(string(empJSON))
23}

خروجی :

1$ go run main.go
2{}

اما خروجی ما یک json خالی است. جرا؟ چون زمانی که اسم فیلد‌ ها با حروف کوچک شروع شوند private هستند و از بیرون قابل دسترسی نیستند. به همین دلیل خروجی یک json خالی است.

برای حل این مشکل ما برای ساختار خودمان یک تگ json اضافه می کنیم و می گوییم اسم فیلد تو در json چیز دیگری است:

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"log"
 7)
 8
 9type employee struct {
10	Name   string `json:"name"`
11	Age    int    `json:"age"`
12	Salary int    `json:"salary"`
13}
14
15func main() {
16	emp := employee{Name: "Sam", Age: 31, Salary: 2000}
17	//Converting to jsonn
18	empJSON, err := json.MarshalIndent(emp, "", "   ")
19	if err != nil {
20		log.Fatalf(err.Error())
21	}
22	fmt.Println(string(empJSON))
23}

خروجی :

1$ go run main.go
2{
3   "name": "Sam",
4   "age": 31,
5   "salary": 2000
6}

فکر می‌کنم خروجی بالا کاملاً برای ما روشن کرد که دقیقاً اون تگ‌هایی که قرار دادیم، برای ما چه کاری انجام دادند. بله کلید-key‌های ما را به اون نام‌هایی که در تگ‌ها نوشته بودیم تغییر دادند.

2.2.6.1 چند نمونه از کاربرد تگ ها #

تگ ها کاربرد های خیلی زیادی دارند که در بخش قرار است بعضی از آنها را بررسی کنیم.

می توانید با تگ (-) مشخص کنید که آن فیلد موقع سریالایز نادیده گرفته شود و نمایش داده نشود. مثال:

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"log"
 7)
 8
 9type employee struct {
10	Name   string `json:"name"`
11	Age    int    `json:"-"`
12	Salary int    `json:"salary"`
13}
14
15func main() {
16	emp := employee{Name: "Sam", Salary: 2000}
17	//Converting to jsonn
18	empJSON, err := json.MarshalIndent(emp, "", "   ")
19	if err != nil {
20		log.Fatalf(err.Error())
21	}
22	fmt.Println(string(empJSON))
23}

خروجی :

1$ go run main.go
2{
3   "name": "Sam",
4   "salary": 2000
5}

با استفاده از تگ omitempty اگر آن فیلد مقداری نداشته باشد، نمایش داده نمی شود:

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"log"
 7)
 8
 9type employee struct {
10	Name   string `json:"name,omitempty"`
11	Age    int    `json:"age,omitempty"`
12	Salary int    `json:"salary,omitempty"`
13}
14
15func main() {
16	emp := employee{Age: 22, Salary: 2000}
17	//Converting to jsonn
18	empJSON, err := json.MarshalIndent(emp, "", "   ")
19	if err != nil {
20		log.Fatalf(err.Error())
21	}
22	fmt.Println(string(empJSON))
23}

خروجی :

1$ go run main.go
2{
3   "age": 22,
4   "salary": 2000
5}

از دیگر کاربرد های تگ ها می توان به عملیات اعتبار سنجی اشاره کرد. برای مثال می توان چک کرد فیلد شماره موبایل از یازده رقم بیشتر و کمتر نباشد. همچنین در تعریف مدل های دیتابیس با استفاده از تگ ها ارتباط بین دیتابیس و مدل را می توانیم پیاده سازی کنیم و …

2.2.7 تعریف فیلد ناشناس در ساختار (struct) #

شما در ساختار struct امکان تعریف فیلدهای ناشناس را دارید و همینطور می‌توانید فیلدهای ناشناس را نیز مقدار دهی کنید.

1type employee struct {
2    string
3    age    int
4    salary int
5}

در کد زیر یک مثال ساده در خصوص تعریف و مقدار دهی فیلدهای ناشناس زده‌ایم:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp := employee{string: "Sam", age: 31, salary: 2000}
13    //Accessing a struct field
14    n := emp.string
15    fmt.Printf("Current name is: %s\n", n)
16    //Assigning a new value
17    emp.string = "John"
18    fmt.Printf("New name is: %s\n", emp.string)
19}
1$ go run main.go
2Current name is: Sam
3New name is: John

توجه داشته باشید زمانی که از فیلد های ناشناس استفاده می کنید، از هر دیتاتایپ فقط یکبار می توانید استفاده کنید:

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7type employee struct {
 8	string // name
 9	int    // age
10	int    // salary
11}
12
13func main() {
14	emp := employee{"alireza", 22, 10_000_000}
15
16	fmt.Printf("%+v", emp)
17}
1$ go run main.go
2# command-line-arguments
3./main.go:10:2: int redeclared
4	./main.go:9:2: other declaration of int
5./main.go:14:33: too many values in struct literal of type employee

2.2.8 تعریف ساختار تو در تو (nested) #

یکی دیگر از امکانات ساختار در زبان گو بحث ساختار تو در تو است. در مثالی که در ادامه زدیم ساختار address را داخل employee قرار دادیم:

 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name    string
 7    age     int
 8    salary  int
 9    address address
10}
11
12type address struct {
13    city    string
14    country string
15}
16
17func main() {
18    address := address{city: "London", country: "UK"}
19    emp := employee{name: "Sam", age: 31, salary: 2000, address: address}
20    fmt.Printf("City: %s\n", emp.address.city)
21    fmt.Printf("Country: %s\n", emp.address.country)
22}
1$ go run main.go
2City: London
3Country: UK

توجه کنید شما طبق روش زیر می‌توانید به فیلدهای تو در تو دسترسی داشته باشید:

1emp.address.city
2emp.address.country

بعضی مواقع بهتر است بصورت مستقیم به فیلد های درون ساختار تو‌در‌تو دسترسی داشته باشیم. به مثال زیر دقت کنید:

 1package main
 2
 3type Product struct {
 4	Name  string
 5	Price int
 6}
 7
 8type Mobile struct {
 9	Product  Product
10	Ram      int
11	SimCount int
12}
13
14func main() {
15	var mobile Mobile = Mobile{}
16	mobile.Product.Name = "Iphone 11"
17	mobile.Product.Price = 1000
18	mobile.Ram = 8
19	mobile.SimCount = 1
20}

همانطور که می بینید برای تعریف اسم موبایل باید بگوییم mobile.Product.Name که این زیاد جالب نیست. پس به این صورت ساختار Product را درون موبایل قرار می دهیم:

 1package main
 2
 3type Product struct {
 4	Name  string
 5	Price int
 6}
 7
 8type Mobile struct {
 9	Product
10	Ram      int
11	SimCount int
12}
13
14func main() {
15	var mobile Mobile = Mobile{}
16	mobile.Name = "Iphone 11"
17	mobile.Price = 1000
18	mobile.Ram = 8
19	mobile.SimCount = 1
20}

الان بصورت مستقیم می توانیم به فیلد های درون Product دسترسی داشته باشیم.

2.2.9 تعریف یک ساختار عمومی یا خصوصی (Public/Private) #

در زبان گو، چیزی به عنوان کلمه کلیدی public یا private جهت تعیین وضعیت دسترسی struct به بیرون وجود ندارد، در عوض کامپایلر گو بر اساس حرف بزرگ یا کوچک عنوان ساختار یا سایر تایپ‌ها، تشخیص می‌دهد تایپ شما عمومی است یا خصوصی. در صورتیکه شما حرف اول را کوچک قرار دهید تایپ شما بیرون از پکیج قابل دسترس نخواهد بود مثل مثال‌های بالا و اگر حرف اول تایپ رو بزرگ قرار دهید، تایپ یا تابع شما بیرون از پکیج نیز در دسترس خواهد بود. مثال تابع fmt.Println.

1type Person struct {
2    Name string
3    age  int
4}
5
6type company struct {
7    Name string
8}
برای اطلاعات بیشتر بهتر است به بخش کپسوله سازی مراجعه کنید.

2.2.10 مقایسه ساختارها #

شما در زبان گو می‌توانید ساختارها را بر اساس عنوان فیلد، تایپ و مقدارشان مقایسه کنید. اما باید توجه کنید ساختارها فقط براساس تایپ‌هایی که در ادامه معرفی کردیم, امکان مقایسه را خواهند داشت:

  • boolean
  • numeric
  • string
  • pointer
  • channel
  • interface types
  • structs
  • array

و اما ۳ تایپ زیر امکان مقایسه را به شما نمی‌دهند:

  • Slice
  • Map
  • Function
 1package main
 2
 3import "fmt"
 4
 5type employee struct {
 6    name   string
 7    age    int
 8    salary int
 9}
10
11func main() {
12    emp1 := employee{name: "Sam", age: 31, salary: 2000}
13    emp2 := employee{name: "Sam", age: 31, salary: 2000}
14    if emp1 == emp2 {
15        fmt.Println("emp1 annd emp2 are equal")
16    } else {
17        fmt.Println("emp1 annd emp2 are not equal")
18    }
19}
1$ go run main.go
2emp1 annd emp2 are equal