Skip to content

Commit f4ae625

Browse files
authored
Merge pull request #395 from amirhasanpour/generics
Update generics season
2 parents f1645f6 + 406741b commit f4ae625

6 files changed

+416
-132
lines changed

content/chapter 6/6.2-generics fundamentals.md

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,30 @@ weight: 11002
2424

2525
**نمونه ساده:**
2626

27-
```go
27+
{{< play >}}
28+
package main
29+
30+
import (
31+
"cmp"
32+
"fmt"
33+
)
34+
2835
// یک تابع ژنریک برای بازگرداندن بیشینه دو مقدار از هر نوع مرتب‌شونده
2936
func Max[T cmp.Ordered](a, b T) T {
30-
if a > b {
31-
return a
32-
}
33-
return b
37+
if a > b {
38+
return a
39+
}
40+
return b
3441
}
35-
```
42+
43+
func main() {
44+
res1 := Max(2, 3)
45+
fmt.Println("Max is: ", res1)
46+
47+
res2 := Max(2.8, 3.1)
48+
fmt.Println("Max is: ", res2)
49+
}
50+
{{< /play >}}
3651

3752
اینجا `[T cmp.Ordered]` می‌گوید T می‌تواند هر نوعی باشد که قابلیت مقایسه داشته باشد (int، float64، string و ...).
3853

@@ -54,11 +69,26 @@ func Max[T cmp.Ordered](a, b T) T {
5469

5570
مثال:
5671

57-
```go
72+
{{< play >}}
73+
package main
74+
75+
import "fmt"
76+
5877
func Print[T any](item T) {
59-
fmt.Println(item)
60-
}
61-
```
78+
fmt.Println(item)
79+
}
80+
81+
func main() {
82+
strSlice := []string{"test1", "test2", "test3"}
83+
intSlice := []int{1, 2, 3}
84+
85+
print("string slice: ")
86+
Print(strSlice)
87+
88+
print("int slice: ")
89+
Print(intSlice)
90+
}
91+
{{< /play >}}
6292

6393
#### ۲. **Constraint (قید/محدودیت)**
6494

@@ -67,12 +97,24 @@ func Print[T any](item T) {
6797

6898
مثال:
6999

70-
```go
71-
func Sum[T Number](a, b T) T { ... }
72-
type Number interface {
73-
int | int64 | float64
74-
}
75-
```
100+
{{< play >}}
101+
package main
102+
103+
import "fmt"
104+
105+
func Sum[T Number](a, b T) T {
106+
return a + b
107+
}
108+
109+
type Number interface {
110+
int | int64 | float64
111+
}
112+
113+
func main() {
114+
fmt.Println(Sum(2, 3))
115+
fmt.Println(Sum(2.8, 3.1))
116+
}
117+
{{< /play >}}
76118

77119
#### ۳. **Type Set (مجموعه نوع)**
78120

content/chapter 6/6.3-generics syntax and structure.md

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,56 @@ type Box[T any] struct {
7070

7171
#### **مثال عملی – Stack ژنریک:**
7272

73-
```go
73+
{{< play >}}
74+
package main
75+
76+
import "fmt"
77+
7478
type Stack[T any] struct {
75-
items []T
79+
items []T
7680
}
7781

7882
func (s *Stack[T]) Push(item T) {
79-
s.items = append(s.items, item)
83+
s.items = append(s.items, item)
8084
}
8185

8286
func (s *Stack[T]) Pop() (T, bool) {
83-
if len(s.items) == 0 {
84-
var zero T
85-
return zero, false
86-
}
87-
idx := len(s.items) - 1
88-
item := s.items[idx]
89-
s.items = s.items[:idx]
90-
return item, true
87+
if len(s.items) == 0 {
88+
var zero T
89+
return zero, false
90+
}
91+
idx := len(s.items) - 1
92+
item := s.items[idx]
93+
s.items = s.items[:idx]
94+
return item, true
9195
}
92-
```
96+
97+
func main() {
98+
intStack := Stack[int]{
99+
items: []int{1, 2, 3},
100+
}
101+
102+
fmt.Println("orginal int stack: ", intStack.items)
103+
intStack.Push(4)
104+
intStack.Push(5)
105+
fmt.Println("int stack after push: ", intStack.items)
106+
intStack.Pop()
107+
fmt.Println("int stack after pop: ", intStack.items)
108+
109+
fmt.Println()
110+
111+
stringStack := Stack[string]{
112+
items: []string{"test1", "test2", "test3"},
113+
}
114+
115+
fmt.Println("orginal string stack: ", stringStack.items)
116+
stringStack.Push("test4")
117+
stringStack.Push("test5")
118+
fmt.Println("string stack after push: ", stringStack.items)
119+
stringStack.Pop()
120+
fmt.Println("string stack after pop: ", stringStack.items)
121+
}
122+
{{< /play >}}
93123

94124
این ساختار را می‌توانید برای `int`، `string`، struct دلخواه و ... به کار ببرید.
95125

content/chapter 6/6.4-generics type sets and constraints.md

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,20 @@ weight: 11004
1818

1919
**مثال ساده:**
2020

21-
```go
21+
{{< play >}}
22+
package main
23+
24+
import "fmt"
25+
26+
func main() {
27+
fmt.Println("int sum: ", Sum(2, 3))
28+
fmt.Println("float sum", Sum(2.2, 3.4))
29+
}
30+
2231
func Sum[T Number](a, b T) T { return a + b }
23-
type Number interface { int | float64 }
24-
```
32+
33+
type Number interface{ int | float64 }
34+
{{< /play >}}
2535

2636
در این مثال، فقط انواعی که در constraint Number تعریف شده‌اند، مجاز هستند.
2737

@@ -33,29 +43,60 @@ type Number interface { int | float64 }
3343

3444
#### **مثال: constraint مبتنی بر متد**
3545

36-
```go
46+
{{< play >}}
47+
package main
48+
49+
import "fmt"
50+
51+
func main() {
52+
person1 := person{
53+
name: "sara",
54+
}
55+
56+
PrintString(&person1)
57+
}
58+
59+
type person struct {
60+
name string
61+
}
62+
63+
func (p *person) String() string {
64+
str := fmt.Sprintf("person name is: %s", p.name)
65+
return str
66+
}
67+
3768
type Stringer interface {
38-
String() string
69+
String() string
3970
}
4071

4172
func PrintString[T Stringer](v T) {
42-
fmt.Println(v.String())
73+
fmt.Println(v.String())
4374
}
44-
```
75+
{{< /play >}}
4576

4677
هر نوعی که متد `String() string` را داشته باشد (مثلاً time.Time یا type خودتان)، می‌تواند برای این تابع استفاده شود.
4778

4879
#### **مثال: constraint مبتنی بر type set (union)**
4980

50-
```go
51-
type Numeric interface { int | int64 | float64 }
81+
{{< play >}}
82+
package main
83+
84+
import "fmt"
85+
86+
func main() {
87+
fmt.Println("Max int is: ", Max(2, 7))
88+
fmt.Println("Max float is: ", Max(2.9, 7.1))
89+
}
90+
91+
type Numeric interface{ int | int64 | float64 }
92+
5293
func Max[T Numeric](a, b T) T {
53-
if a > b {
54-
return a
55-
}
56-
return b
94+
if a > b {
95+
return a
96+
}
97+
return b
5798
}
58-
```
99+
{{< /play >}}
59100

60101
فقط انواع عددی مجاز به استفاده از Max هستند.
61102

@@ -91,31 +132,50 @@ Go چندین constraint از پیش تعریف‌شده دارد:
91132

92133
- فقط نوع‌هایی که می‌توان با == یا != مقایسه کرد (برای map key یا مجموعه‌ها):
93134

94-
```go
95-
func Contains[T comparable](slice []T, v T) bool {
96-
for _, item := range slice {
97-
if item == v {
98-
return true
99-
}
100-
}
101-
return false
102-
}
103-
```
135+
{{< play >}}
136+
package main
137+
138+
import "fmt"
104139

140+
func main() {
141+
slice := []int{1, 2, 3, 4, 5, 6}
142+
result := Contains(slice, 2)
143+
fmt.Println(result)
144+
}
145+
146+
func Contains[T comparable](slice []T, v T) bool {
147+
for _, item := range slice {
148+
if item == v {
149+
return true
150+
}
151+
}
152+
return false
153+
}
154+
{{< /play >}}
105155

106156
#### **Ordered** (از پکیج cmp، Go 1.21+)
107157

108158
برای انواعی که می‌توان از <, >, <=, >= استفاده کرد (int, float, string):
109159

110-
```go
111-
import "cmp"
112-
func Min[T cmp.Ordered](a, b T) T {
113-
if a < b {
114-
return a
115-
}
116-
return b
117-
}
118-
```
160+
{{< play >}}
161+
package main
162+
163+
import (
164+
"cmp"
165+
"fmt"
166+
)
167+
168+
func main() {
169+
fmt.Println("Min is: ", Min(2, 7))
170+
}
171+
172+
func Min[T cmp.Ordered](a, b T) T {
173+
if a < b {
174+
return a
175+
}
176+
return b
177+
}
178+
{{< /play >}}
119179

120180
## ۶.۴.۴ ساخت constraint سفارشی و ترکیبی (union constraints)
121181

0 commit comments

Comments
 (0)