当前位置:网站首页>Golang generics: generics
Golang generics: generics
2022-06-11 04:12:00 【whz-emm】
Use non generic functions
golang In the absence of generics , If we want to calculate a map All of the value The sum of the , Let's say map Of key by string type ,value yes int64 type , We need to define the following functions :
// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
At the same time we have another map You also need to calculate all value The sum of the , The map Of key Also for the string type , however value yes float64 type , So we need to define another function :
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}Then call the two functions respectively to perform the calculation operation
1. Define two first map
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
}
// Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}2. Call function
fmt.Printf("Non-Generic Sums: %v and %v\n",
SumInts(ints),
SumFloats(floats))You can find SumInts and SumFloats Except for different receiving parameters, the internal logic is exactly the same , If there are more functions with different parameter types but complete function logic , You will find duplicate code everywhere , So we have generics to solve this problem
Using generic functions
Defining generic functions
To achieve the same calculation map Of value The sum of the , You can define the following functions :
// SumIntsOrFloats sums the values of map m. It supports both int64 and float64
// as types for map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}- This function declares two type parameters , namely [] Medium K and V, And a to use these two type parameters map Parameters of type m, Return to one V Type value
- among comparable It's a go There are predefined types , Express K This parameter needs to support == and != operation
- So it can be understood that this function receives a map Parameters , The map Of key It's a comparable Type value ,value yes int64 perhaps float Type value , So define a map[int]int64 It can also be calculated with this function , because int The type is also a comparable Parameters of type , You can do it == and != operation
Call function
fmt.Printf("Generic Sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))One function solves the problem , If you want to add int type ,float Type or other type , It's just [] Add the corresponding type to the , There is no need to rewrite another function
Type derivation
go The compiler will automatically deduce the parameter types when calling generic functions , Therefore, you can omit the passed in parameter types when calling generic functions
Call function
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))Declare type constraints
stay [] A is defined in V Type parameter of , When there are only a few types, it is clear to see , If there are many types , such as float,float64,int,int64,int32 Etc., etc. , It doesn't look so clear , So you can declare a type constraint , Define a Number Type of interface, The type is int64 or float64, If there are other types, you can always add
1. Define type constraints
type Number interface {
int64 | float64
}2. Use type constraints
// SumNumbers sums the values of map m. It supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}3. Call function
fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))summary
Generics are designed to solve the problem of too much duplicate code , The best practices are as follows :
1. Declare type constraints on variables that contain many types , Use this type constraint directly in generic functions
2. There is no need to add a type when calling a generic function
Full text code attached :
package main
import "fmt"
type Number interface {
int64 | float64
}
func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
}
// Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
intsInts := map[int]int64{
0: 10,
1: 20,
}
fmt.Printf("Non-Generic Sums: %v and %v\n",
SumInts(ints),
SumFloats(floats))
fmt.Printf("Generic Sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("Generic Sums with Constraint: %v and %v and %v\n",
SumNumbers(ints),
SumNumbers(floats),
SumNumbers(intsInts))
}
// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// SumIntsOrFloats sums the values of map m. It supports both int64 and float64
// as types for map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers sums the values of map m. It supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}The results are as follows :
$ go run generic.go
Non-Generic Sums: 46 and 62.97
Generic Sums: 46 and 62.97
Generic Sums, type parameters inferred: 46 and 62.97
Generic Sums with Constraint: 46 and 62.97 and 30Reference resources
Tutorial: Getting started with generics - The Go Programming Language
边栏推荐
- 【CustomView】Glide+BitmapTransformation 图片上下边框波浪处理(WaveTransformation)
- Market prospect analysis and Research Report of digital line scan camera in 2022
- Embedded basic interface -spi
- Possible problems with password retrieval function (supplementary)
- QT日志模块的个性化使用
- 未来已来,5G-Advanced时代开启
- Market prospect analysis and Research Report of Ethernet scanner in 2022
- Unity prefab scene 冲突合并工具 UnityYAMLMerge
- Embedded basic interface-i2c
- 6. form label
猜你喜欢

未來已來,5G-Advanced時代開啟

PMM monitoring Oracle

A - Eddy's AC puzzle (C language)

Guide de migration Maui

6. 表格标签

Sslstrip Ultimate - location hijacking
![[激光器原理与应用-2]:国内激光器重点品牌](/img/55/a87169bb75429f323159e3b8627cc6.jpg)
[激光器原理与应用-2]:国内激光器重点品牌

编程大作战 -- 挑战高考题

Cloud broadcast alert, guanghetong helps intelligent camera to build a "river protection" drowning prevention system

Rational use of thread pool and thread variables
随机推荐
Market prospect analysis and Research Report of nitrogen liquefier in 2022
域名解析耗时是什么?域名解析耗时影响因素有哪些?
clickjacking漏洞的挖掘与利用
7. 列表标签
使用工具类按一定规则读取Excel文件
给你一个项目,你将如何开展性能测试工作?
2022爱分析· 隐私计算厂商全景报告 | 爱分析报告
【服务器数据恢复】同友存储raid5崩溃的数据恢复案例
【CustomView】Glide+BitmapTransformation 图片上下边框波浪处理(WaveTransformation)
[signalr complete series] Net6 Zhongshi signalr communication
写给通信年轻人的27个忠告
Embedded basic interface-i2s
Management system of College Students' associations based on SSM
店铺门面转让出租小程序开发制作功能介绍
Discussion on the development trend of remote power management unit (Intelligent PDU)
Market prospect analysis and Research Report of pipe and hose press fitting tools in 2022
众昂矿业:氟化工是萤石的主要消耗领域
超简单 CameraX 人脸识别效果封装
[cnn]|differences between CNN and transformer
密码找回功能可能存在的问题(补充)