dongsi2317 2017-11-08 11:42
浏览 60
已采纳

如何使用派生类型进行sync.Map

My goal is to have a custom type the one I could derive and add extra methods, for example, when using a map 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
", x)
}

But if want the same with sync.Map how to do it? I am currently trying this: https://play.golang.org/p/8PjpPY-Sjq

package main

import (
    "fmt"
    "sync"
)

type myMap sync.Map

func (m *myMap) Add() {
    _, ok := (*m).Load("test")
    println(ok)
}

func main() {
    x := &myMap{}
    fmt.Printf("x = %+v
", x)
}

But get this error:

(*m).Load undefined (type myMap has no field or method Load)

Any ideas?

  • 写回答

2条回答 默认 最新

  • du8794 2017-11-08 11:51
    关注

    The Go Programming Language Specification

    Struct types

    A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.

    StructType    = "struct" "{" { FieldDecl ";" } "}" .
    FieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .
    EmbeddedField = [ "*" ] TypeName .
    Tag           = string_lit .
    

    A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.

    A field or method f of an embedded field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.

    Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.

    Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:

    • If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.

    • If S contains an embedded field *T, the method sets of S and *S both include promoted methods with receiver T or *T.


    Use an embedded field of a struct. For example,

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

    Playground: https://play.golang.org/p/YCNeiYVhlT

    Output:

    true
    test 42 true
    

    The Go Programming Language Specification

    Selectors

    For a primary expression x that is not a package name, the selector expression

    x.f
    

    denotes the field or method f of the value x (or sometimes *x; see below). The identifier f is called the (field or method) selector; it must not be the blank identifier. The type of the selector expression is the type of f. If x is a package name, see the section on qualified identifiers.

    A selector f may denote a field or method f of a type T, or it may refer to a field or method f of a nested embedded field of T. The number of embedded fields traversed to reach f is called its depth in T. The depth of a field or method f declared in T is zero. The depth of a field or method f declared in an embedded field A in T is the depth of f in A plus one.

    Rule 1:

    For a value x of type T or *T where T is not a pointer or interface type, x.f denotes the field or method at the shallowest depth in T where there is such an f. If there is not exactly one f with shallowest depth, the selector expression is illegal.


    Sometimes, there is ambiguity in complex cases of nested embedding. If so, specify the full qualifiers explicitly. For example, m.Map.LoadOrStore and 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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C
  • ¥15 请问RTX4060的笔记本电脑可以训练yolov5模型吗?
  • ¥15 数学建模求思路及代码
  • ¥50 silvaco GaN HEMT有栅极场板的击穿电压仿真问题