Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何为sync.Map使用派生类型_Go - Fatal编程技术网

Go 如何为sync.Map使用派生类型

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) } 但是

我的目标是拥有一个自定义类型,即我可以派生并添加额外方法的类型,例如,在使用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)
}
但是如果想要同样的东西怎么办呢?我目前正在尝试:

但是得到这个错误:

(*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)
}