Go 如何为sync.Map使用派生类型
我的目标是拥有一个自定义类型,即我可以派生并添加额外方法的类型,例如,在使用this works时:Go 如何为sync.Map使用派生类型,go,Go,我的目标是拥有一个自定义类型,即我可以派生并添加额外方法的类型,例如,在使用this works时: package main import "fmt" type myMap map[string]string func (m *myMap) Add() { _, ok := (*m)["test"] println(ok) } func main() { x := &myMap{} fmt.Printf("x = %+v\n", x) } 但是
package main
import "fmt"
type myMap map[string]string
func (m *myMap) Add() {
_, ok := (*m)["test"]
println(ok)
}
func main() {
x := &myMap{}
fmt.Printf("x = %+v\n", x)
}
但是如果想要同样的东西怎么办呢?我目前正在尝试:
但是得到这个错误:
(*m).Load undefined (type myMap has no field or method Load)
有什么想法吗
结构是一系列命名元素,称为字段,每个元素
它有一个名称和一个类型。可以显式指定字段名
(IdentifierList)或隐式(EmbeddedField)。在结构中,
非空字段名称必须是唯一的
StructType = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] .
EmbeddedField = [ "*" ] TypeName .
Tag = string_lit .
用类型声明但没有显式字段名的字段称为
嵌入字段。必须将嵌入字段指定为类型名T
或者作为指向非接口类型名称*T的指针,而T本身可能不是
必须是指针类型。非限定类型名用作字段名
调用结构x中嵌入字段的字段或方法f
如果x.f是表示该字段或方法的合法选择器,则升级
f
提升字段与结构的普通字段类似,只是
不能用作结构的复合文本中的字段名
给定一个结构类型S和一个名为T的类型,升级的方法是
包含在结构的方法集中,如下所示:
- 如果S包含一个嵌入字段T,则S和*S的方法集都包括与接收器T一起升级的方法 还包括使用receiver*T的提升方法
- 如果S包含嵌入字段*T,则S和*S的方法集都包括具有接收器T或*T的提升方法
使用
结构的嵌入字段
。比如说,
package main
import (
"fmt"
"sync"
)
type myMap struct {
sync.Map
}
func (m *myMap) Add(key, value interface{}) bool {
_, loaded := m.LoadOrStore(key, value)
return !loaded
}
func main() {
x := &myMap{}
k := "test"
ok := x.Add(k, 42)
fmt.Println(ok)
v, ok := x.Load(k)
fmt.Println(k, v, ok)
}
游乐场:
输出:
true
test 42 true
对于不是包名称的主表达式x,选择器 表情
x.f
表示值x的字段或方法f(有时为*x;请参阅
下)。标识符f称为(字段或方法)选择器;信息技术
不能是空白标识符。选择器表达式的类型
是f的类型。如果x是一个包名,请参阅“限定”一节
标识符
选择器f可以表示T类型的字段或方法f,也可以
参考T的嵌套嵌入字段的字段或方法f
为达到f而遍历的嵌入字段数称为f的深度
T.在T中声明的字段或方法f的深度为零。深度
在T中的嵌入字段a中声明的字段或方法f的
f在A+1中的深度
规则1:
对于类型为T或*T的值x,其中T不是指针或接口
类型,x.f表示T中最浅深度处的场或方法
哪里有这样一个f。如果没有一个f与
最浅的深度,选择器表达式是非法的
有时,在嵌套嵌入的复杂情况下存在歧义。如果是,请显式指定完整限定符。例如,
m.Map.LoadOrStore
和x.Map.Load
package main
import (
"fmt"
"sync"
)
type myMap struct {
sync.Map
}
func (m *myMap) Add(key, value interface{}) bool {
_, loaded := m.Map.LoadOrStore(key, value)
return !loaded
}
func main() {
x := &myMap{}
k := "test"
ok := x.Add(k, 42)
fmt.Println(ok)
v, ok := x.Map.Load(k)
fmt.Println(k, v, ok)
}
行:
type myMap sync.Map
基于现有类型定义新类型
根据报告:
定义的类型可能有与其关联的方法。事实并非如此
继承绑定到给定类型的任何方法
这意味着,myMap
只继承sync.Map
(它是一个struct
)的字段,而不是它的方法。它不像其他语言中的类继承那样工作
具体来说,sync.Map
没有任何导出字段,因此使用它来定义新类型毫无意义。
相反,您应该将包含sync.Map
的struct
类型定义为字段。然后您就可以访问它的方法@彼得索的回答说明了如何做到这一点
package main
import (
"fmt"
"sync"
)
type myMap struct {
sync.Map
}
func (m *myMap) Add(key, value interface{}) bool {
_, loaded := m.Map.LoadOrStore(key, value)
return !loaded
}
func main() {
x := &myMap{}
k := "test"
ok := x.Add(k, 42)
fmt.Println(ok)
v, ok := x.Map.Load(k)
fmt.Println(k, v, ok)
}