Terdapat beberapa alternatif kepada generik dalam Go, termasuk: 1. Antara Muka: membenarkan definisi set kaedah, dan jenis yang berbeza boleh melaksanakan antara muka yang sama untuk mencapai gelagat yang sama 2. Jenis penegasan: semak jenis pada masa jalan dan daya penukaran, yang boleh mencapai sesuatu yang serupa dengan tingkah laku jenis generik 3. Penjanaan kod: Hasilkan kod yang cekap berdasarkan jenis pada masa penyusunan 4. Refleksi: Semak dan kendalikan jenis semasa runtime, dan boleh membuat dan memanggil kod yang ditaip secara dinamik untuk mencapai tingkah laku generik; .
Bahasa Go ialah bahasa yang ditaip secara statik dan mempunyai batasan tertentu dalam sokongan generik tradisional. Walau bagaimanapun, terdapat beberapa alternatif untuk mencapai fungsi seperti generik.
Antaramuka ialah mekanisme keselamatan jenis yang membolehkan mentakrifkan satu set kaedah tanpa perlu menentukan jenis data tertentu. Anda boleh mencipta jenis yang berbeza dengan tingkah laku yang sama dengan melaksanakan antara muka.
type Sortable interface { Less(other Sortable) bool } type IntSorter struct { ints []int } func (s IntSorter) Less(other Sortable) bool { return s.ints[0] < other.(IntSorter).ints[0] } type StringSorter struct { strings []string } func (s StringSorter) Less(other Sortable) bool { return s.strings[0] < other.(StringSorter).strings[0] }
Dengan cara ini kita boleh mencipta jenis IntSorter dan StringSorter dengan gelagat pengisihan yang sama sambil mengekalkan keselamatan jenis.
Jenis penegasan membenarkan penyemakan jenis dan penghantaran pada masa tayangan. Ini boleh digunakan untuk mengesan dan menukar nilai, membolehkan tingkah laku seperti generik.
func SortAnything(data interface{}) { switch v := data.(type) { case []int: sort.Ints(v) case []string: sort.Strings(v) default: panic("Unsupported type") } }
Tegasan jenis membolehkan kami mengendalikan pelbagai jenis data, tetapi kami perlu sedar tentang overhed pemeriksaan jenis dan kemungkinan ralat masa jalan.
Penjanaan kod ialah teknik untuk mencipta tingkah laku generik dengan menjana kod yang ditaip. Ini boleh dilakukan pada masa penyusunan, menghasilkan jenis kod cekap tertentu.
import "github.com/dave/jennifer/jen" func GenerateSorter(t string) string { code := jen.NewFile("sorter") code.Func().Id("Sort" + t).Params(jen.Id("data").Index().Id(t)).BlockFunc(func(g *jen.Group) { g.Sort().Id(t).Call(jen.Id("data")) }) return code.GoString() } func main() { intSorter := GenerateSorter("int") stringSorter := GenerateSorter("string") fmt.Println(intSorter) }
Melalui penjanaan kod, kami boleh menjana fungsi pengisihan cekap secara dinamik yang menyasarkan jenis tertentu.
Reflection membenarkan program untuk memeriksa dan memanipulasi jenis semasa runtime. Ia boleh digunakan untuk mencipta dan memanggil kod ditaip secara dinamik untuk mencapai tingkah laku seperti generik.
func SortAnythingReflect(data interface{}) { t := reflect.TypeOf(data) if t.Kind() != reflect.Slice { panic("Unsupported type") } v := reflect.ValueOf(data) sort := reflect.MakeFunc(t.Method(by("Less")).Type(), func(args []reflect.Value) []reflect.Value { a := args[0].Interface() b := args[1].Interface() if a.(Comparable).Less(b) { return []reflect.Value{reflect.ValueOf(true)} } return []reflect.Value{reflect.ValueOf(false)} }) sort.Call([]reflect.Value{v, v}) }
Reflection menyediakan cara yang sangat fleksibel untuk melaksanakan tingkah laku generik, tetapi ia lebih mahal daripada alternatif lain dan boleh mengakibatkan kod yang sukar dibaca dan dikekalkan.
Atas ialah kandungan terperinci Apakah alternatif kepada ubat generik dalam golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!