extension methods in golang?

huangapple go评论101阅读模式
英文:

extension methods in golang?

问题

我是一个.NET开发者,对Go语言非常陌生。

在.NET中,我们有扩展方法。Go语言中有类似的东西吗?

在.NET中,我会这样写:bsonTrans["trans.ticket"]

其中,bsonTrans是bson文档,"trans.ticket"是JSON中的键,trans是外层级别,ticket是内层级别。

我正在使用原生的MongoDB驱动程序。我会添加我的扩展函数来执行这些操作。

在.NET中,我可以一直做到第n层。

我想在Go语言中应用相同的逻辑。

示例

b := []byte(trans)
var config map[string]interface{}
err := json.Unmarshal(b, &config)

fmt.Println(config["data"].(map[string]interface{})["issued"])

例如,在这个示例中,我可以这样做吗:

config["data.issued"],它会返回对应的值吗?

请帮我弄清楚这个问题...

实际的JSON:

(实际的JSON非常大,但我提供了一个包含较少字段的示例。)

{
    "_id": 2001,
    "address": {
        "line1": "",
        "line2": "",
        "line3": ""
    },
    "tickets": [
        {
            "seq": 2,
            "add": [
                {
                    "seq": "",
                    "amnt": 50
                },
                {
                    "seq": "",
                    "amnt": 50
                },
                {
                    "seq": "",
                    "amnt": 50
                }
            ]
        }
    ]
}

不使用结构体的原因是我的JSON有太多嵌套结构,并且我有超过10个具有不同结构的模式。

所以我放弃了使用结构体。

我承认我不确定是否省略结构体是最好的方式。

英文:

I am a .NET guy. Very much new to the Go language.

In .NET we have extension methods. Is there anything equivalent in Go?

In .NET I will do like bsonTrans["trans.ticket"]

in that bsonTrans => bson document

    "trans.ticket" => key in json
    
     trans is outer level and

     ticket is inner level

I am using native mongodb driver. In that I add my extension functions to perform these operations.

Like wise up to the nth level I did it .NET.

I would like to apply the same logic in Go.

Example

 b := []byte(trans)
var config map[string]interface{}
err := json.Unmarshal(b, &config)

fmt.Println(config["data"].(map[string] interface{})["issued"])

For instance in that example, can i do something like:

config["data.issued"] which should give the value in return ?

Please help me in figuring this out...

Actual json :-

(The actual json is too big, however I am providing a sample of it with less fields.)

{
 "_id" : 2001,
    "address" : {
        "line1" : "",
        "line2" : "",
        "line3" : ""
       },
    "tickets" : [ 
        {
            "seq" : 2,
            "add" : [
              {
              "seq" : "",
              "amnt" : 50
              },

              {
              "seq" : "",
              "amnt" : 50
              {
              "seq" : "",
              "amnt" : 50
              }
              }
              
              }
             ]
}

Reason for not using struct is my json has too many nested structures and I have more than 10 schemas with different structures.

So I left out structs.

I admit that I am not sure that omitting structs is the best way.

答案1

得分: 33

扩展方法在.NET中的实现方式不被支持。

你可以通过创建一个字符串类型并在该类型上创建一个方法来实现类似的功能:

type MyString string

func (m *MyString) Method() {
}

func main() {
    var s MyString = ""
    s.Method()
}
英文:

Extension methods are not supported the way it is in .NET.

The closest thing you can do is create a type from string and create a method on that type:

type MyString string
func (m *MyString) Method() {
}

func main() {
    var s MyString = ""
    s.Method()
}

答案2

得分: 5

更新2017年:

Go确实支持接收器类型的扩展方法。

基于Go 1.9中的类型断言,你可以在定义类型时简单地添加=,然后在其上添加方法。

type NewStruct = OldStrut
func (m *NewStruct) ExtensionMethod() {
}

调用它的方式如下:

func main() {
    s := OldStruct{}
    s.ExtensionMethod()
}
英文:

Update 2017:

Go does support extension methods for receiver types.

Based on type assertions in Go 1.9, you can simply add = where you define the type, then add methods to it.

type NewStruct = OldStrut
func (m *NewStruct) ExtensionMethod() {
}

To call it:

func main() {
    s := OldStruct{}
    s.ExtensionMethod()
}

答案3

得分: 1

这是一个使用你的 JSON 的代码示例。你的 JSON 示例不是有效的,所以我根据我认为的你的意图进行了更正。

我认为使用一个深层嵌套的结构体的 map[string]interface{} 可能行不通,但我不知道你的用例,所以不能确定。

这是一个可以运行该代码的交互链接:http://play.golang.org/p/0gtYMfBMWX

package main

import "fmt"
import "encoding/json"

func main() {
  b := []byte(`{
  "tickets": [
    {
      "add": [
        {
          "amnt": 50,
          "seq": ""
        },
        {
          "amnt": 50,
          "seq": ""
        },
        {
          "amnt": 50,
          "seq": ""
        }
      ],
      "seq": 2
    }
  ],
  "address": {
    "line3": "",
    "line2": "",
    "line1": ""
  },
  "_id": 2001
}`)
  var config map[string]interface{}
  if err := json.Unmarshal(b, &config); err != nil {
    fmt.Printf("Error: %s", err)
    return
  }

  // 我不确定你想要获取数据的哪一部分...
  //fmt.Println(config["data"].(map[string]interface{})["issued"])

  fmt.Printf("%v\n\n", config)

  tickets := config["tickets"]
  fmt.Printf("%v\n\n", tickets)

}

希望对你有帮助!

英文:

Here is a sample of code that uses your json. Your json sample wasn't valid, so I corrected it to what I think your intent was.

I think you will find using a map[string]interface{} with a deeply nested struct will not work out, but I don't know your use case, so I can't say for sure.

Here is an interactive link that runs the code as well: http://play.golang.org/p/0gtYMfBMWX

package main

import "fmt"
import "encoding/json"

func main() {
  b := []byte(`{
  "tickets": [
    {
      "add": [
        {
          "amnt": 50,
          "seq": ""
        },
        {
          "amnt": 50,
          "seq": ""
        },
        {
          "amnt": 50,
          "seq": ""
        }
      ],
      "seq": 2
    }
  ],
  "address": {
    "line3": "",
    "line2": "",
    "line1": ""
  },
  "_id": 2001
}`)
  var config map[string]interface{}
  if err := json.Unmarshal(b, &config); err != nil {
    fmt.Printf("Error: %s", err)
    return
  }

  // I'm not sure what part of the data you are trying to get at here...
  //fmt.Println(config["data"].(map[string]interface{})["issued"])

  fmt.Printf("%v\n\n", config)

  tickets := config["tickets"]
  fmt.Printf("%v\n\n", tickets)

}

huangapple
  • 本文由 发表于 2014年3月4日 01:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/22153309.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定