如何在Golang中转换地图类型

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

How to convert type of map in golang

问题

函数B的返回类型是map[T][]T,代码如下:

type T interface{}

func B() map[T][]T {
  result := make(map[T][]T)
  return result
}

现在我有一个函数A调用函数B,代码如下:

func A() map[string][]string {
  res := B()
  return res.(map[string][]string) //我确定类型是map[string][]string,所以我使用断言,但是它不起作用
}

那么,我该如何处理map类型的类型转换呢?

英文:

The function B return type map[T][]T like this:

type T interface{}

func B() map[T][]T {
  result := make(map[T][]T)
  return result
}

And now I have a function A call function B like this:

func A() map[string][]string {
  res := B()
  return res.(map[string][]string) //I'm sure the type is map[string][]string, so I use assertion, but it doesn't works
}

So, how can I do this cover type of map?

答案1

得分: 3

你无法直接进行类型转换,因为它们是完全不同的类型。你需要逐个复制和类型转换每个项目。以下是示例代码的翻译:

import "fmt"

type T interface{}

func B() map[T][]T {
	result := make(map[T][]T)
	return result
}

func A() map[string][]string {
	res := B()
	result := make(map[string][]string)
	for k, v := range res {
		key := k.(string)
		value := make([]string, 0, len(res))
		for i := 0; i < len(value); i += 1 {
			value[i] = v[i].(string)
		}
		result[key] = value
	}
	return result
}

func main() {
	fmt.Println("Hello, playground", A())
}

希望对你有所帮助!

英文:

You can't. Those are completely different types.
You have to copy and type cast item by item: http://play.golang.org/p/uhLPytbhpR

import &quot;fmt&quot;

type T interface{}

func B() map[T][]T {
	result := make(map[T][]T)
	return result
}

func A() map[string][]string {
	res := B()
	result := make(map[string][]string)
	for k,v := range res {
		key := k.(string)	
		value := make([]string, 0, len(res))
		for i := 0; i&lt;len(value); i +=1 {
			value[i] = v[i].(string)
		}
		result[key]= value
	}
	return result
}

func main() {
	fmt.Println(&quot;Hello, playground&quot;, A())
}

答案2

得分: 2

另一种方法是返回T而不是map[T][]Tplay

type T interface{}

func B() T {
    result := map[string][]string{
        "test": {"test", "test"},
    }
    return T(result)
}

func A() map[string][]string {
    res := B()
    if v, ok := res.(map[string][]string); ok {
        return v
    }
    return nil
}

func main() {
    fmt.Println("Hello, playground", A())
}

// 编辑,转换函数:http://play.golang.org/p/cW_PNTqauV

func makeMap() map[T][]T {
    return map[T][]T{
        "test":  {"test", "test"},
        "stuff": {"stuff", 1212, "stuff"},
        1:       {10, 20},
    }
}

func convertMap(in map[T][]T) (out map[string][]string) {
    out = make(map[string][]string, len(in))
    for k, _ := range in {
        if ks, ok := k.(string); ok {
            v := in[k] // 这样我们在for循环中不会使用副本
            out[ks] = make([]string, 0, len(v))
            for i := range v {
                if vs, ok := v[i].(string); ok {
                    out[ks] = append(out[ks], vs)
                } else {
                    fmt.Printf("错误:%v(%T)不是字符串。\n", v[i], v[i])
                }

            }
        } else {
            fmt.Printf("错误:%v(%T)不是字符串。\n", k, k)
        }

    }
    return
}

func main() {
    fmt.Println(convertMap(makeMap()))
}
英文:

A different approach is to return T not map[T][]Tplay:

type T interface{}

func B() T {
	result := map[string][]string{
		&quot;test&quot;: {&quot;test&quot;, &quot;test&quot;},
	}
	return T(result)
}

func A() map[string][]string {
	res := B()
	if v, ok := res.(map[string][]string); ok {
		return v
	}
	return nil
}

func main() {
	fmt.Println(&quot;Hello, playground&quot;, A())
}

// Edit, converter function : http://play.golang.org/p/cW_PNTqauV

func makeMap() map[T][]T {
	return map[T][]T{
		&quot;test&quot;: {&quot;test&quot;, &quot;test&quot;},
		&quot;stuff&quot;: {&quot;stuff&quot;, 1212, &quot;stuff&quot;},
		1: {10, 20},
	}
}

func convertMap(in map[T][]T) (out map[string][]string) {
	out = make(map[string][]string, len(in))
	for k, _ := range in {
		if ks, ok := k.(string); ok {
			v := in[k] // this way we won&#39;t use a copy in the for loop
			out[ks] = make([]string, 0, len(v))
			for i := range v {
				if vs, ok := v[i].(string); ok {
					out[ks] = append(out[ks], vs)
				} else {
					fmt.Printf(&quot;Error: %v (%T) is not a string.\n&quot;, v[i], v[i])
				}
				
			}
		} else {
			fmt.Printf(&quot;Error: %v (%T) is not a string.\n&quot;, k, k)
		}
		
	}
	return
}

func main() {
	fmt.Println(convertMap(makeMap()))
}

huangapple
  • 本文由 发表于 2014年6月5日 09:32:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/24050232.html
匿名

发表评论

匿名网友

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

确定