Same method on different types and return different type value in Go

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

Same method on different types and return different type value in Go

问题

我已经看到了类似的问题(在Go中对不同数组类型使用相同的方法)。

但在我的情况下,我的函数不返回相同的类型。

你能否将下面的代码简化一些?

package main

import (
  "encoding/json"
  "fmt"
)

type A struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}

type B struct {
  Name    string `json:"name"`
  Age     int    `json:"age"`
  Address string `json:"address"`
}

func UnmarshalA(b []byte) *A {
  var t *A
  _ = json.Unmarshal(b, &t)
  return t
}

func UnmarshalB(b []byte) *B {
  var t *B
  _ = json.Unmarshal(b, &t)
  return t
}

func main() {
  a := []byte(`{"name": "aaaa", "age": 1}`)
  unmarshal_a := UnmarshalA(a)
  fmt.Println(unmarshal_a.Name)

  b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
  unmarshal_b := UnmarshalB(b)
  fmt.Println(unmarshal_b.Name)
}

输出结果为:

aaaa
bbbb

链接:https://play.golang.org/p/PF0UgkbSvk

英文:

I've seen some similar question(Same method on different array types in Go)

But in my case my functions do not return same types.

Can you write the below code more simply?

package main

import (
  "encoding/json"
  "fmt"
)

type A struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}

type B struct {
  Name    string `json:"name"`
  Age     int    `json:"age"`
  Address string `json:address`
}

func UnmarshalA(b []byte) *A {
  var t *A
  _ = json.Unmarshal(b, &t)
  return t
}

func UnmarshalB(b []byte) *B {
  var t *B
  _ = json.Unmarshal(b, &t)
  return t
}

func main() {
  a := []byte(`{"name": "aaaa", "age": 1}`)
  unmarshal_a := UnmarshalA(a)
  fmt.Println(unmarshal_a.Name)

  b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
  unmarshal_b := UnmarshalB(b)
  fmt.Println(unmarshal_b.Name)
}

// aaaa
// bbbb

https://play.golang.org/p/PF0UgkbSvk

答案1

得分: 2

你有几个选择。

  1. 不要费心使用UnmarshalAUnmarshalB。它们实际上没有做太多事情,你只是在抽象出一行代码... var t *A

  2. 如果你实际上不需要AB结构体,只是想要以可用的方式表示JSON字符串的内容,你可以将其解组为map[string]interface{}

例如:

package main

import (
    "encoding/json"
    "fmt"
)

func UnmarshalAny(b []byte) map[string]interface{} {
    var t = make(map[string]interface{})
    _ = json.Unmarshal(b, &t)
    return t
}

func main() {
    a := []byte(`{"name": "aaaa", "age": 1}`)
    unmarshal_a := UnmarshalAny(a)

    b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
    unmarshal_b := UnmarshalAny(b)

    // 访问方式如下...
    fmt.Println(unmarshal_a["name"])
    fmt.Println(unmarshal_b["name"])
}

点击此处查看示例

如果你想通过引用传递数据,你可以将代码更改为以下形式:

package main

import (
    "encoding/json"
    "fmt"
)

func UnmarshalAny(b []byte) *map[string]interface{} {
    var t = make(map[string]interface{})
    _ = json.Unmarshal(b, &t)
    return &t
}

func main() {
    a := []byte(`{"name": "aaaa", "age": 1}`)
    unmarshal_a := UnmarshalAny(a)

    b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
    unmarshal_b := UnmarshalAny(b)

    // 访问方式如下...
    fmt.Println((*unmarshal_a)["name"])
    fmt.Println((*unmarshal_b)["name"])
}

点击此处查看示例

英文:

You have a couple of options.

  1. Don't bother using UnmarshalA and UnmarshalB.
    They're really not doing much and you're really only abstracting away a single line... var t *A

  2. If you don't actually need the A and B structs and simply want the contents of the JSON string represented in a way you can use it, you could just unmarshal into a map[string]interface{}.

E.g.

package main

import (
    "encoding/json"
    "fmt"
)

func UnmarshalAny(b []byte) map[string]interface{} {
    var t = make(map[string]interface{})
    _ = json.Unmarshal(b, &t)
    return t
}

func main() {
    a := []byte(`{"name": "aaaa", "age": 1}`)
    unmarshal_a := UnmarshalAny(a)

    b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
    unmarshal_b := UnmarshalAny(b)

    // Accessed like this...
    fmt.Println(unmarshal_a["name"])
    fmt.Println(unmarshal_b["name"])
}

https://play.golang.org/p/KaxBlNsCDR

If you wanted to pass the data by reference then you would change it to something like this:

package main

import (
	"encoding/json"
	"fmt"
)

func UnmarshalAny(b []byte) *map[string]interface{} {
	var t = make(map[string]interface{})
	_ = json.Unmarshal(b, &t)
	return &t
}

func main() {
	a := []byte(`{"name": "aaaa", "age": 1}`)
	unmarshal_a := UnmarshalAny(a)

    b := []byte(`{"name": "bbbb", "age": 2, "address": "b@example.com"}`)
    unmarshal_b := UnmarshalAny(b)

	// Accessed like this...
	fmt.Println((*unmarshal_a)["name"])
    fmt.Println((*unmarshal_b)["name"])
}

https://play.golang.org/p/AXKYCCMJQU

huangapple
  • 本文由 发表于 2017年5月11日 16:12:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/43909930.html
匿名

发表评论

匿名网友

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

确定