代码之家  ›  专栏  ›  技术社区  ›  ncopiy

在实例生成期间修改结构字段

  •  1
  • ncopiy  · 技术社区  · 6 年前

    外部应用程序API为我提供了一个JSON格式的名称列表。我需要修改所有这些。
    但我不喜欢为它编写一些循环(特别是在Python与反射和其他东西一起使用之后)

    有没有什么方法可以在go中编写类似的内容?

    type MyIncredibleType struct {
        Name    ModifyName  // ModifyName is not a type!
    } 
    
    func ModifyName(input string) string {
        return input + ".com"
    }
    

    预期的行为是:

    a := MyIncredibleType{Name: "Abracadabra"}
    print(a.Name) // Abracadabra.com
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Zanicar    6 年前

    假设我正确理解你的问题,我觉得这很直接:

    // ModifyName func
    func ModifyName(input string) string {
        return fmt.Sprintf("%v.com", input)
    }
    

    如果您希望在类型本身内实现这一点,而不修改(改变)内部状态:

    type MyType sturct {
        name string // unexported
    }
    
    // accessor func to return name
    func (t MyType) Name() string {
        return t.name
    }
    
    // accessor func to return modified name
    func (t MyType) ModifiedName() string {
        return fmt.Sprintf("%v.com", t.name)
    }
    

    如果要修改内部状态:

    type MyType struct {
        name string
    }
    
    // mutator func (note the pointer for pass by reference)
    func (t *MyType) ModifyName(input string) {
        t.name = fmt.Sprintf("%v.com", input)
    }
    
    // accessor (note no pointer for pass by value)
    func (t MyType) Name() string {
        return t.name
    }
    
        2
  •  1
  •   Himanshu    6 年前

    这在Go中是不可能的。这不是结构在go中的工作方式。

    type MyIncredibleType struct {
        Name    ModifyName `json:"name"`  // ModifyName is not a type!
    }
    

    您只能定义 Built-in 结构字段的类型,或者可以定义 Composite Literal 类型。

    复合文本为结构、数组、切片和 每次评估时都映射并创建一个新值。它们组成 文本的类型,后面是元素的大括号绑定列表。 每个元素前面都可以有相应的键。

    尝试创建一个结构的方法接收器,用于解析来自API的JSON来修改名称。这会让你达到你想要的目标。

    package main
    
    import (
        "fmt"
    )
    
    type MyIncredibleType struct {
        Name    string `json:"name"`  // ModifyName is not a type!
    } 
    
    func(myIncredibleType *MyIncredibleType) ModifyName() string {
        return myIncredibleType.Name+".com"
    }
    
    func main() {
        a := MyIncredibleType{Name: "Abracadabra"}
        name := a.ModifyName()
        fmt.Printf("%s",name)
    }
    

    Playground Example

    或者,可以传递一个接口,该接口将用名称字段包装任何结构值,然后使用类型断言获取基础值以修改该值并返回结果:

    package main
    
    import (
        "fmt"
    )
    
    type MyIncredibleType struct {
        Name    string `json:"name"`  // ModifyName is not a type!
    } 
    
    func ModifyName(input interface{}) string{
            return input.(interface{}).(string)+".com"
    }
    
    func main() {
        a := MyIncredibleType{Name: "Abracadabra"}
        name := ModifyName(a.Name)
        fmt.Printf("%s",name)
    }
    

    上的工作代码 Go Playground

    有关更多信息,请访问 Golang method Declarations 关于如何创建接收器。