మాడ్యూల్ పాఠాలు (3/5)
జెనరిక్స్ (గో 1.18+)
గో 1.18 (మార్చి 2022) నుండి, రకం పారామితులు అందుబాటులో ఉన్నాయి: విధులు మరియు రకాలను రకాలుగా పారామితి చేయవచ్చు. వారు మిమ్మల్ని Map, Filter, Set[T], LinkedList[T]ని డూప్లికేట్ కోడ్ లేకుండా మరియు interface{} + రన్టైమ్ రకం నిర్దారణలు లేకుండా వ్రాయడానికి అనుమతిస్తారు.
సాధారణ విధి: వాక్యనిర్మాణం
func Map[T, U any](s []T, f func(T) U) []U {
out := make([]U, len(s))
for i, v := range s {
out[i] = f(v)
}
return out
}
doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// doubled is []int{2, 4, 6}మూడు కొత్త అంశాలు:
[T, U any]పేరు తర్వాత: టైప్ పారామితులను వాటి పరిమితులతో ప్రకటిస్తుంది.any= ఏదైనా రకాన్ని ఆమోదించే పరిమితి (గో 1.18 నుండిinterface{}యొక్క మారుపేరు).- అనుమతి:
Map([]int{...}, ...)కి కాల్ చేయడం ద్వారా మీరుMap[int, int](...)అని వ్రాయవలసిన అవసరం లేదు: కంపైలర్T=int, U=intని అంచనా వేస్తుంది.
కొన్నిసార్లు అనుమితి సరిపోదు (ఉదా., T ఆర్గ్యుమెంట్లు లేని కన్స్ట్రక్టర్లు) మరియు స్పష్టమైన తక్షణం అవసరం: New[*Server]().
అంతర్నిర్మిత పరిమితులు
| నిర్బంధం | అర్థం |
|---|---|
any | ఏదైనా రకం (== interface{}). |
comparable | == మరియు !=తో రకాలు: సంఖ్యా, స్ట్రింగ్, బూల్, పాయింటర్లు, ఛానెల్లు, పోల్చదగిన శ్రేణులు/నిర్మాణాలు. |
comparable సమానత్వాన్ని అనుమతిస్తుంది కానీ కాదు < లేదా >.
func Index[T comparable](s []T, x T) int {
for i, v := range s {
if v == x { return i }
}
return -1
}</> కోసం మీకు అనుకూల పరిమితి అవసరం.
అనుకూల పరిమితి: రకం యూనియన్లు
నిర్బంధం అనేది "టైప్ ఎలిమెంట్" క్లాజులతో కూడిన ఇంటర్ఫేస్:
type Ordered interface {
~int | ~int64 | ~float64 | ~string
}
func Min[T Ordered](a, b T) T {
if a < b { return a }
return b
}|= యూనియన్: జాబితా చేయబడిన ఏవైనా రకాలను అంగీకరిస్తుంది.~int= "int లేదా ఏదైనా రకంtype X int" (అదే అంతర్లీన రకంతో).~లేకుండా, ఖచ్చితమైనintమాత్రమే.
ఒక ప్రతిబంధకం కూడా మిక్స్ మెథడ్స్ మరియు టైప్ ఎలిమెంట్స్:
type Stringable interface {
~string
Len() int
}సాధారణ రకాలు
విధులు మాత్రమే కాదు: స్ట్రక్ట్లు మరియు ఇంటర్ఫేస్లు కూడా టైప్ పారామితులను కలిగి ఉంటాయి.
type Set[T comparable] struct {
m map[T]struct{}
}
func NewSet[T comparable]() *Set[T] {
return &Set[T]{m: make(map[T]struct{})}
}
func (s *Set[T]) Add(v T) { s.m[v] = struct{}{} }
func (s *Set[T]) Has(v T) bool { _, ok := s.m[v]; return ok }
s := NewSet[string]()
s.Add("ada")పద్ధతులు రకాన్ని మించి టైప్ పారామితులను జోడించలేవు: func (s *Set[T]) MapTo[U any](...) కంపైల్ చేయదు (ఉద్దేశపూర్వక రూపకల్పన పరిమితి).
జెనరిక్స్ ఎప్పుడు ఉపయోగించాలి
అవును ఎప్పుడు:
- అనేక రకాల (సేకరణలు, అల్గారిథమ్లు,
Map/Filter/Reduceవంటి సహాయకులు) కోసం తర్కం నిజంగా ఒకేలా ఉంటుంది. - ప్రత్యామ్నాయం కోడ్ డూప్లికేటింగ్ లేదా
interface{}+ రకం ధృవీకరణలను ఉపయోగించడం (రకం భద్రతను కోల్పోతుంది).
లేదు ఎప్పుడు:
- ఒకటి లేదా రెండు పద్ధతులతో ఇంటర్ఫేస్ సరిపోతుంది మరియు మరింత చదవగలిగేది (
io.Reader,fmt.Stringer). - మీరు "ఎందుకంటే మీరు చేయగలరు" అని పరామితి చేస్తున్నారు: ఒకే వినియోగ సందర్భం → దాని యొక్క నిర్దిష్ట సంస్కరణను రూపొందించండి.
వ్యాయామాలు
Definisci la funzione generica Min[T Ordered](a, b T) T che ritorna il Minore usando l'operatore <. Il constraint è già fornito ఆర్డర్ చేయబడింది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
అమలు మ్యాప్[T, U ఏదైనా](లు []T, f func(T) U) []U: అప్లికేషన్ ఎఫ్ ఎ ఓగ్ని ఎలిమెంటో మరియు రిస్టిట్యూయిస్ ఇల్ న్యూవో స్లైస్.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
క్వాలే పరిమితి అంతర్నిర్మిత సమ్మతి అనుమతి == నా నాన్ ఆపరేటర్ <?
func Index[T ???](s []T, x T) int { ... }