在一个具有interface{}值的map上实现String()方法。

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

Implement String() on a map with interface{} values

问题

你好!以下是你提供的Go(Golang)代码的翻译:

package main

import (
	"bytes"
	"fmt"
	"log"
	"reflect"
)

type MyDictionary map[string]interface{}

func (d MyDictionary) String() string {
	var stringBuffer bytes.Buffer

	for key, value := range d {
		stringBuffer.WriteString(key)
		stringBuffer.WriteString(": ")

		valueType := reflect.TypeOf(value).Kind()

		switch valueType {
		case reflect.String:
			log.Println("string") // 仅用于检查此代码块是否执行
			// 添加到stringBuffer

		case reflect.Float64:
			log.Println("float64") // 仅用于检查此代码块是否执行
			// 添加到stringBuffer

		default:
			log.Println("错误:类型为", valueType)
		}
	}

	return stringBuffer.String()
}

func main() {
	var dict MyDictionary = make(MyDictionary)
	dict["hello"] = "world"
	dict["floating"] = 10.0
	dict["whole"] = 12

	fmt.Println(dict)
}

我将String()函数修改为了正确的形式。你可以尝试运行这段代码,它会输出你期望的结果。在Go中,我们使用reflect.TypeOf(value).Kind()来获取值的类型。然后,你可以根据类型将值添加到stringBuffer中。

希望这可以帮助到你!如果你有任何其他问题,请随时问我。

英文:

How could I write a function to print a map object in Go (Golang)? Right now I have this, but it doesn't compile. It returns cannot convert value (type interface {}) to type reflect.Kind: need type assertion.

package main

type MyDictionary map[string]interface{}

func (d MyDictionary) String() string {
    var stringBuffer bytes.Buffer

    for key, value := range d {
        stringBuffer.WriteString(key)
        stringBuffer.WriteString(": ")

        valueType := reflect.Kind(value)

        switch valueType {
        case reflect.String:
            log.Println("string") // just to check if this block gets executed
            // Add to stringBuffer

        case reflect.Float64:
            log.Println("float64") // just to check if this block gets executed
            // Add to stringBuffer

        default:
            log.Println("Error: type was", valueType)
        }
    }

    return stringBuffer.String()
}

func main() {
    var dict MyDictionary = make(MyDictionary)
    dict["hello"] = "world"
    dict["floating"] = 10.0
    dict["whole"] = 12
    
    fmt.Println(dict)
}

I want String() to return a string like hello: world\nfloating: 10.0\nwhole: 12\n. That I can then pass to fmt.Println() to print this. In Java, I would use StringBuilder for this.

hello: world
floating: 10.0
whole: 12

I also tried switching on value.(type) with case string: and case float64, but then I didn't know how to write those values to stringBuffer.

答案1

得分: 5

以下是一个惯用的解决方案。

func (d MyDictionary) String() string {
    var buf bytes.Buffer

    for k, v := range d {
        buf.WriteString(k + ": ")

        // v is an interface{} here
        switch v := v.(type) {
        // The inner v is typed. It shadows the outer interface{} v. That's
        // the idiomatic part.
        case string:
            buf.WriteString(v + "\n") // v is a string
        case int:
            buf.WriteString(fmt.Sprintln(v)) // v is an int
        case float64:
            buf.WriteString(fmt.Sprintln(v)) // v is a float64
        }
    }

    return buf.String()
}

这段代码是一个自定义字典类型的方法,用于将字典转换为字符串表示。它使用了一个缓冲区(bytes.Buffer)来逐个处理字典中的键值对。根据值的类型,使用不同的方式将键值对添加到缓冲区中。最后,将缓冲区转换为字符串并返回。

英文:

Here's an idiomatic solution.

func (d MyDictionary) String() string {
	var buf bytes.Buffer

	for k, v := range d {
		buf.WriteString(k + ": ")

		// v is an interface{} here
		switch v := v.(type) {
		// The inner v is typed. It shadows the outer interface{} v. That's
		// the idiomatic part.
		case string:
			buf.WriteString(v + "\n") // v is a string
		case int:
			buf.WriteString(fmt.Sprintln(v)) // v is an int
		case float64:
			buf.WriteString(fmt.Sprintln(v)) // v is a float64
		}
	}

	return buf.String()
}

答案2

得分: 1

你可以将其简化为以下形式(playground):

func (d MyDictionary) String() string {
    var result string

    for key, value := range d {
        result += fmt.Sprintf("%s: %v\n", key, value)
    }

    return result
}

打印结果为:

hello: world
floating: 10
whole: 12

显然,“whole”浮点数已经去除了小数位(如果将其设置为10.5,则会正确打印)。如果需要保留小数位数,那么你可以使用switch语句并指定精度(playground):

func (d MyDictionary) String() string {
    var result string

    for key, value := range d {
        switch value.(type) {
        case float64:
            result += fmt.Sprintf("%s: %.2f\n", key, value)
        default:
            result += fmt.Sprintf("%s: %v\n", key, value)
        }
    }

    return result
}

打印结果为:

floating: 10.00
whole: 12
hello: world
英文:

You can potentially simplify it to this (<kbd>playground</kbd>):

func (d MyDictionary) String() string {
    var result string

    for key, value := range d {
        result += fmt.Sprintf(&quot;%s: %v\n&quot;, key, value)
    }

    return result
}

Which prints:

hello: world
floating: 10
whole: 12

Obviously, the "whole" floating point has the decimals removed (if you set it to 10.5 it will print properly). If that's required, then you'll want to switch on the float and specify precision as well (<kbd>playground</kbd>):

func (d MyDictionary) String() string {
    var result string

    for key, value := range d {
    	switch value.(type) {
    	case float64:
		    result += fmt.Sprintf(&quot;%s: %.2f\n&quot;, key, value)
	    default:
		    result += fmt.Sprintf(&quot;%s: %v\n&quot;, key, value)
	    }
    }

    return result
}

Which prints:

floating: 10.00
whole: 12
hello: world

答案3

得分: -1

你需要获取接口的类型,然后根据类型进行切换。

valueType := reflect.TypeOf(value).Kind()

工作示例:http://play.golang.org/p/a-7SePUzZ-

package main

import (
	"bytes"
	"fmt"
	"log"
	"reflect"
)

type MyDictionary map[string]interface{}

func (d MyDictionary) String() string {
	var stringBuffer bytes.Buffer

	for key, value := range d {
		stringBuffer.WriteString(key)
		stringBuffer.WriteString(": ")

		valueType := reflect.TypeOf(value).Kind()

		switch valueType {
		case reflect.String:
			log.Println("string")
		default:
			log.Println("类型是:", valueType)
		}
	}

	return stringBuffer.String()
}

func main() {
	var dict MyDictionary = make(MyDictionary)
	dict["hello"] = "world"
	dict["floating"] = 10.0
	dict["whole"] = 12

	fmt.Println(dict)
}

输出结果:

2009/11/10 23:00:00 string
2009/11/10 23:00:00 类型是: float64
2009/11/10 23:00:00 类型是: int
hello: floating: whole:
英文:

You need to get the type of the interface and then switch on the kind of the type.

valueType := reflect.TypeOf(value).Kind()

Working Example: http://play.golang.org/p/a-7SePUzZ-

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;log&quot;
	&quot;reflect&quot;
)

type MyDictionary map[string]interface{}

func (d MyDictionary) String() string {
	var stringBuffer bytes.Buffer

	for key, value := range d {
		stringBuffer.WriteString(key)
		stringBuffer.WriteString(&quot;: &quot;)

		valueType := reflect.TypeOf(value).Kind()

		switch valueType {
		case reflect.String:
			log.Println(&quot;string&quot;)
		default:
			log.Println(&quot;Type was:&quot;, valueType)
		}
	}

	return stringBuffer.String()
}

func main() {
	var dict MyDictionary = make(MyDictionary)
	dict[&quot;hello&quot;] = &quot;world&quot;
	dict[&quot;floating&quot;] = 10.0
	dict[&quot;whole&quot;] = 12

	fmt.Println(dict)
}

Output

2009/11/10 23:00:00 string
2009/11/10 23:00:00 Type was: float64
2009/11/10 23:00:00 Type was: int
hello: floating: whole: 

huangapple
  • 本文由 发表于 2014年7月8日 07:58:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/24621768.html
匿名

发表评论

匿名网友

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

确定