- vừa được xem lúc

Generics in Golang

0 0 21

Người đăng: VND

Theo Viblo Asia

Since Go lang version 1.18 , expected feature named generics added to the language. We will practice this feature, from old approach in Go before vesion 1.18 (e.g, 1.17 version), then we use new syntax support generics feature. In these below code snippets, we use latest version of Go lang at the time of writing (Go version 1.20.2)

Add student by fullname

Old way (Go lang 1.17): Add student by array, slice without generics

package main import "fmt" func addStudent(students []string, student string) []string { return append(students, student)
} func main() { students := []string{} result := addStudent(students, "Nguyen Thanh Van") result = addStudent(result, "Nguyen Tri Hung") result = addStudent(result, "Pham Van Tam") fmt.Println(result)
} // Result
// [Nguyen Thanh Van Nguyen Tri Hung Pham Van Tam]

Add stutdent by id

package main import "fmt" func addStudent(students []string, student string) []string { return append(students, student)
} func addStudentID(studentIDs []int, studentId int) []int { return append(studentIDs, studentId)
} func main() { studentIDs := []int{} result := addStudentID(studentIDs, 32) result = addStudentID(result, 33) result = addStudentID(result, 34) fmt.Println(result)
} // Result
// [32 33 34]

Add student by struct

package main import "fmt" func addStudentStrut(studentStructs []StudentStruct, st StudentStruct) []StudentStruct{ return append(studentStructs, st)
} type StudentStruct struct{ Name string ID int Age int
} func main() { students := []StudentStruct{} // Empty slice result := addStudentStrut(students, StudentStruct{"Nguyen Dieu An", 1, 35}) result = addStudentStrut(result, StudentStruct{"Tran Van Thuong", 2, 30}) result = addStudentStrut(result, StudentStruct{"Le Van Tam", 3, 25}) fmt.Println(result)
} // Result
// [{Nguyen Dieu An 1 35} {Tran Van Thuong 2 30} {Le Van Tam 3 25}]

Add student by generics

package main import "fmt" type Stringer = interface { String() string
} type Integer int func (i Integer) String() string { return fmt.Sprintf("%d", i)
} type String string func (s String) String() string { return string(s)
} type Student struct { Name string ID int Age int
} func (s Student) String() string { return fmt.Sprintf("%s %d %d", s.Name, s.ID, s.Age)
} func addStudent[T Stringer](students []T, student T) []T { return append(students, student)
} func main() { students := []String{} // Empty slice result := addStudent[String](students, "Nguyen Dieu An") result = addStudent[String](result, "Tran Van Thuong") result = addStudent[String](result, "Le Van Tam") fmt.Println(result) students1 := []Integer{} // Empty slice result1 := addStudent[Integer](students1, 35) result1 = addStudent[Integer](result1, 30) result1 = addStudent[Integer](result1, 25) fmt.Println(result1) students3 := []Student{} // Empty slice result3 := addStudent[Student](students3, Student{"Nguyen Dieu An", 1, 35}) result3 = addStudent[Student](result3, Student{"Tran Van Thuong", 2, 30}) result3 = addStudent[Student](result3, Student{"Le Van Tam", 3, 25}) fmt.Println(result3)
} // Result
// [Nguyen Dieu An Tran Van Thuong Le Van Tam]
// [35 30 25]
// [Nguyen Dieu An 1 35 Tran Van Thuong 2 30 Le Van Tam 3 25]

We need define interface by this way: Any type that implement a String() function can be considered to be of type Stringer.

More compact: remove explicit type declaration of generic function

package main import "fmt" type Stringer = interface { String() string
} type Integer int func (i Integer) String() string { return fmt.Sprintf("%d", i)
} type String string func (s String) String() string { return string(s)
} type Student struct { Name string ID int Age int
} func (s Student) String() string { return fmt.Sprintf("%s %d %d", s.Name, s.ID, s.Age)
} func addStudent[T Stringer](students []T, student T) []T { return append(students, student)
} func main() { students := []String{} // Empty slice result := addStudent(students, "Nguyen Dieu An") result = addStudent(result, "Tran Van Thuong") result = addStudent(result, "Le Van Tam") fmt.Println(result) students1 := []Integer{} // Empty slice result1 := addStudent(students1, 35) result1 = addStudent(result1, 30) result1 = addStudent(result1, 25) fmt.Println(result1) students3 := []Student{} // Empty slice result3 := addStudent(students3, Student{"Nguyen Dieu An", 1, 35}) result3 = addStudent(result3, Student{"Tran Van Thuong", 2, 30}) result3 = addStudent(result3, Student{"Le Van Tam", 3, 25}) fmt.Println(result3)
} // Result
// [Nguyen Dieu An Tran Van Thuong Le Van Tam]
// [35 30 25]
// [Nguyen Dieu An 1 35 Tran Van Thuong 2 30 Le Van Tam 3 25]

Loose type by keyword any in generics function

package main import "fmt" type Student struct { Name string ID int Age int
} func addStudent[T any](students []T, student T) []T { return append(students, student)
} func main() { students := []string{} // Empty slice result := addStudent(students, "Nguyen Dieu An") result = addStudent(result, "Tran Van Thuong") result = addStudent(result, "Le Van Tam") fmt.Println(result) students1 := []int{} // Empty slice result1 := addStudent(students1, 35) result1 = addStudent(result1, 30) result1 = addStudent(result1, 25) fmt.Println(result1) students3 := []Student{} // Empty slice result3 := addStudent(students3, Student{"Nguyen Dieu An", 1, 35}) result3 = addStudent(result3, Student{"Tran Van Thuong", 2, 30}) result3 = addStudent(result3, Student{"Le Van Tam", 3, 25}) fmt.Println(result3)
} // Result
// [Nguyen Dieu An Tran Van Thuong Le Van Tam]
// [35 30 25]
// [Nguyen Dieu An 1 35 Tran Van Thuong 2 30 Le Van Tam 3 25]

Conclusion

We go through these stages:

  1. Add Student by seperate functions by concrete data type: integer, string, struct
  2. Define interface, then use Generics
  3. Use Generics and remove explicit type (compact syntax)
  4. Use Generics for loosest by using key any, it is no contraint to a number of concrete types, for all types. Benefit we seen, source code becomes compact, can re-use easily.

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 131

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 56

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 60

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 75

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 54