-
-
Notifications
You must be signed in to change notification settings - Fork 115
Update generics season #395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughDocumentation updates convert multiple Go examples in chapter 6 to interactive playground embeds and runnable demos. Minor formatting adjustments occur in interface declarations. One bug fix updates a method call (Int → Int()) in a non-generic Max example. No public API signatures are changed. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
content/chapter 6/6.2-generics fundamentals.md (1)
13-17: Fix author name and unify “ژنریک” spelling.Correct “Ian Lance Taylor” and keep “ژنریک” consistent across the page.
-**یه جمله ای از Ian lancer tailor هست:** +**نقلقولی از Ian Lance Taylor:** -زمانی باید از جنریک استفاده کرد که کد شما بواسطه تغییر تایپ تکرار می شود یا اینکه برای کاهش assertion از جنریک استفاده کنیم. +زمانی باید از ژنریک استفاده کرد که کد شما بهواسطه تغییر نوع تکراری میشود یا برای کاهش type assertion از ژنریک استفاده میکنید.
🧹 Nitpick comments (9)
content/chapter 6/6.5-generics examples and practical.md (3)
193-215: Rename variables to match the data structure (Queue).Variables are named Stack in a Queue example; rename for clarity.
- stringStack := Queue[string]{ + stringQueue := Queue[string]{ data: []string{"test1", "test2", "test3"}, } - fmt.Println(stringStack) - stringStack.Enqueue("test4") - stringStack.Enqueue("test5") - fmt.Println(stringStack) - stringStack.Dequeue() - fmt.Println(stringStack) + fmt.Println(stringQueue) + stringQueue.Enqueue("test4") + stringQueue.Enqueue("test5") + fmt.Println(stringQueue) + stringQueue.Dequeue() + fmt.Println(stringQueue) - intStack := Queue[int]{ + intQueue := Queue[int]{ data: []int{1, 2, 3}, } - fmt.Println(intStack) - intStack.Enqueue(4) - intStack.Enqueue(5) - fmt.Println(intStack) - intStack.Dequeue() - fmt.Println(intStack) + fmt.Println(intQueue) + intQueue.Enqueue(4) + intQueue.Enqueue(5) + fmt.Println(intQueue) + intQueue.Dequeue() + fmt.Println(intQueue)
87-106: Use a clearer predicate name.“prediction” misleads; prefer a predicate-style name.
- res := Filter(testSlice, prediction) + res := Filter(testSlice, isTestTask) ... -func prediction(str string) bool { +func isTestTask(str string) bool { return strings.Contains(str, "test") }
317-337: Missing import for errors in the repo example (if made runnable).The snippet uses errors.New but doesn’t import errors. If you convert this to a {{< play >}} block later, add the import.
content/chapter 6/6.6-comparing generics with solutions before Go 1.18.md (1)
14-21: Clean up extra blank lines flagged by markdownlint.Resolve MD012 (no-multiple-blanks) around the playground fence and after main for a cleaner diff and passing lint.
Also applies to: 36-41
content/chapter 6/6.3-generics syntax and structure.md (1)
102-106: Fix typos: “orginal” → “original”.Minor text polish in demo output.
- fmt.Println("orginal int stack: ", intStack.items) + fmt.Println("original int stack: ", intStack.items) ... - fmt.Println("orginal string stack: ", stringStack.items) + fmt.Println("original string stack: ", stringStack.items)Also applies to: 115-121
content/chapter 6/6.2-generics fundamentals.md (2)
85-90: Prefer fmt.Println over the built-in print for consistency/output stream.Use fmt for labeled output alongside fmt.Println in Print.
- print("string slice: ") + fmt.Println("string slice:") ... - print("int slice: ") + fmt.Println("int slice:")
27-50: Address markdownlint warnings (MD010/MD046).Tabs inside code blocks and an indented code block were flagged. Either replace tabs with spaces in code blocks or configure markdownlint to ignore fenced/shortcode code sections; also convert any indented blocks to fenced.
Also applies to: 72-92, 100-117
content/chapter 6/6.4-generics type sets and constraints.md (2)
26-29: Nit: make output labels consistentAdd a colon to the second println to match the first one’s label.
- fmt.Println("float sum", Sum(2.2, 3.4)) + fmt.Println("float sum:", Sum(2.2, 3.4))
68-74: Prefer using the standard fmt.Stringer instead of redefining StringerLeverage the built-in interface to avoid duplication and align with Go conventions.
-type Stringer interface { - String() string -} - -func PrintString[T Stringer](v T) { +func PrintString[T fmt.Stringer](v T) { fmt.Println(v.String()) }Optionally, you could rely on formatting to call String implicitly:
func PrintString[T fmt.Stringer](v T) { fmt.Println(v) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
content/chapter 6/6.2-generics fundamentals.md(3 hunks)content/chapter 6/6.3-generics syntax and structure.md(1 hunks)content/chapter 6/6.4-generics type sets and constraints.md(3 hunks)content/chapter 6/6.5-generics examples and practical.md(3 hunks)content/chapter 6/6.6-comparing generics with solutions before Go 1.18.md(1 hunks)content/chapter 6/6.7-limitations, errors, and anti-patterns in generics.md(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
content/chapter 6/6.6-comparing generics with solutions before Go 1.18.md
28-28: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
37-37: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
content/chapter 6/6.2-generics fundamentals.md
33-33: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
47-47: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
79-79: Hard tabs
Column: 1
(MD010, no-hard-tabs)
83-83: Hard tabs
Column: 1
(MD010, no-hard-tabs)
87-87: Hard tabs
Column: 1
(MD010, no-hard-tabs)
88-88: Hard tabs
Column: 1
(MD010, no-hard-tabs)
89-89: Hard tabs
Column: 1
(MD010, no-hard-tabs)
90-90: Hard tabs
Column: 1
(MD010, no-hard-tabs)
91-91: Hard tabs
Column: 1
(MD010, no-hard-tabs)
100-100: Hard tabs
Column: 1
(MD010, no-hard-tabs)
102-102: Hard tabs
Column: 1
(MD010, no-hard-tabs)
102-102: Code block style
Expected: fenced; Actual: indented
(MD046, code-block-style)
103-103: Hard tabs
Column: 1
(MD010, no-hard-tabs)
104-104: Hard tabs
Column: 1
(MD010, no-hard-tabs)
105-105: Hard tabs
Column: 1
(MD010, no-hard-tabs)
106-106: Hard tabs
Column: 1
(MD010, no-hard-tabs)
107-107: Hard tabs
Column: 1
(MD010, no-hard-tabs)
109-109: Hard tabs
Column: 1
(MD010, no-hard-tabs)
111-111: Hard tabs
Column: 1
(MD010, no-hard-tabs)
112-112: Hard tabs
Column: 1
(MD010, no-hard-tabs)
113-113: Hard tabs
Column: 1
(MD010, no-hard-tabs)
115-115: Hard tabs
Column: 1
(MD010, no-hard-tabs)
116-116: Hard tabs
Column: 1
(MD010, no-hard-tabs)
117-117: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (5)
content/chapter 6/6.7-limitations, errors, and anti-patterns in generics.md (1)
124-127: Resolved: Verified Go 1.24/1.25 features Generic type aliases were added in Go 1.24 and the core types notion was removed in Go 1.25 per the official release notes (tip.golang.org)content/chapter 6/6.6-comparing generics with solutions before Go 1.18.md (1)
26-33: LGTM: Correct fix using bv.Int().The reflect-based comparison now correctly calls Int() on reflect.Value.
content/chapter 6/6.4-generics type sets and constraints.md (3)
81-99: LGTM: clear Numeric constraint and Max implementationExample compiles and demonstrates union type-set constraints well.
135-154: LGTM: idiomatic Contains with comparableStraightforward and correct; good use of comparable.
160-178: LGTM: Ordered example with cmp is correctAccurate use of cmp.Ordered and a minimal Min implementation.
| strGet, ok := stringStack.Get(1) | ||
| if !ok { | ||
| log.Println("not find") | ||
| } | ||
| fmt.Println("founded: ", strGet) | ||
|
|
||
| fmt.Println() | ||
|
|
||
| intStack := List[int]{ | ||
| items: []int{1, 2, 3}, | ||
| } | ||
| fmt.Println(intStack) | ||
| intStack.Add(4) | ||
| intStack.Add(5) | ||
| fmt.Println(intStack) | ||
| intGet, ok := intStack.Get(1) | ||
| if !ok { | ||
| log.Println("not find") | ||
| } | ||
| fmt.Println("founded: ", intGet) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix user-facing messages (“not found”, “found”).
Minor English fixes in logs/prints.
- if !ok {
- log.Println("not find")
- }
- fmt.Println("founded: ", strGet)
+ if !ok {
+ log.Println("not found")
+ }
+ fmt.Println("found: ", strGet)
...
- if !ok {
- log.Println("not find")
- }
- fmt.Println("founded: ", intGet)
+ if !ok {
+ log.Println("not found")
+ }
+ fmt.Println("found: ", intGet)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| strGet, ok := stringStack.Get(1) | |
| if !ok { | |
| log.Println("not find") | |
| } | |
| fmt.Println("founded: ", strGet) | |
| fmt.Println() | |
| intStack := List[int]{ | |
| items: []int{1, 2, 3}, | |
| } | |
| fmt.Println(intStack) | |
| intStack.Add(4) | |
| intStack.Add(5) | |
| fmt.Println(intStack) | |
| intGet, ok := intStack.Get(1) | |
| if !ok { | |
| log.Println("not find") | |
| } | |
| fmt.Println("founded: ", intGet) | |
| } | |
| strGet, ok := stringStack.Get(1) | |
| if !ok { | |
| log.Println("not found") | |
| } | |
| fmt.Println("found: ", strGet) | |
| fmt.Println() | |
| intStack := List[int]{ | |
| items: []int{1, 2, 3}, | |
| } | |
| fmt.Println(intStack) | |
| intStack.Add(4) | |
| intStack.Add(5) | |
| fmt.Println(intStack) | |
| intGet, ok := intStack.Get(1) | |
| if !ok { | |
| log.Println("not found") | |
| } | |
| fmt.Println("found: ", intGet) | |
| } |
🤖 Prompt for AI Agents
In content/chapter 6/6.5-generics examples and practical.md around lines 255 to
275, update the user-facing messages for correctness: replace log.Println("not
find") with log.Println("not found") (both occurrences) and change
fmt.Println("founded: ", ...) to fmt.Println("found:", ...) to use proper
English and consistent punctuation/capitalization.
| package main | ||
|
|
||
| import "fmt" | ||
|
|
||
| func PrintMapKeys[K comparable, V any](m map[K]V) { | ||
| for k := range m { | ||
| fmt.Println(k) | ||
| } | ||
| for k := range m { | ||
| fmt.Println(k) | ||
| } | ||
| } | ||
|
|
||
| PrintMapKeys(map[[]int]int{}) // error: []int does not implement comparable | ||
| func main() { | ||
| PrintMapKeys(map[[]int]int{}) // error: []int does not implement comparable | ||
|
|
||
| // use this instead: | ||
| // testMap := make(map[string]int) | ||
| // PrintMapKeys(testMap) | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Make the error demo compile while still illustrating the issue.
The current main triggers a compile-time error and isn’t runnable. Keep the invalid call as a commented line with the expected error, and enable the valid example so the snippet runs.
func main() {
- PrintMapKeys(map[[]int]int{}) // error: []int does not implement comparable
+ // Compile-time error example (intentionally invalid):
+ // PrintMapKeys(map[[]int]int{}) // []int does not implement comparable
+
+ // Use this instead:
+ testMap := make(map[string]int)
+ PrintMapKeys(testMap)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| package main | |
| import "fmt" | |
| func PrintMapKeys[K comparable, V any](m map[K]V) { | |
| for k := range m { | |
| fmt.Println(k) | |
| } | |
| for k := range m { | |
| fmt.Println(k) | |
| } | |
| } | |
| PrintMapKeys(map[[]int]int{}) // error: []int does not implement comparable | |
| func main() { | |
| PrintMapKeys(map[[]int]int{}) // error: []int does not implement comparable | |
| // use this instead: | |
| // testMap := make(map[string]int) | |
| // PrintMapKeys(testMap) | |
| } | |
| ``` | |
| package main | |
| import "fmt" | |
| func PrintMapKeys[K comparable, V any](m map[K]V) { | |
| for k := range m { | |
| fmt.Println(k) | |
| } | |
| } | |
| func main() { | |
| // Compile-time error example (intentionally invalid): | |
| // PrintMapKeys(map[[]int]int{}) // []int does not implement comparable | |
| // Use this instead: | |
| testMap := make(map[string]int) | |
| PrintMapKeys(testMap) | |
| } |
🤖 Prompt for AI Agents
In content/chapter 6/6.7-limitations, errors, and anti-patterns in generics.md
around lines 62 to 79, the main function currently contains an actual invalid
call PrintMapKeys(map[[]int]int{}) which causes a compile-time error; comment
out that invalid call and keep a brief comment showing the expected error, then
enable the valid example by creating a concrete map (e.g., testMap :=
make(map[string]int) or a literal) and calling PrintMapKeys(testMap) so the
snippet compiles and still demonstrates the limitation.
6.2.1 => Make the code executable
6.2.2.1 => Make the code executable
6.2.2.2 => Make the code executable
6.3.2 => Make stack example executable
6.4.1 => Make the code executable
6.4.2.1 => Make the code executable
6.4.2.2 => Make the code executable
6.4.3 => Make the comparable example executable
6.4.3 => Make the ordered example executable
6.5.1.1 => Make the code executable
6.5.1.2 => Make the code executable
6.5.1.3 => Make the code executable
6.5.2.1 => Make the code executable
6.5.2.2 => Make the code executable
6.5.2.3 => Make the code executable
6.6.1 => Fix package not found error
6.7.2 => Explain correct situation too
Summary by CodeRabbit