Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Struct Golang在结构之间切换_Struct_Go_Interface_Switch Statement - Fatal编程技术网

Struct Golang在结构之间切换

Struct Golang在结构之间切换,struct,go,interface,switch-statement,Struct,Go,Interface,Switch Statement,我是golang的新手,我正在尝试创建一个函数,该函数基于它所使用的结构,将使用Sprintf返回格式化字符串 type Name struct { Title string First string Last string } type Location struct { Street string City string State string Zip string } func Merge(m interface{

我是golang的新手,我正在尝试创建一个函数,该函数基于它所使用的结构,将使用Sprintf返回格式化字符串

type Name struct {
    Title string
    First string
    Last  string
}

type Location struct {
    Street string
    City   string
    State  string
    Zip    string
}

func Merge(m interface{}) string {
    switch m.(type) {
    case *Location:
        return fmt.Sprintf("%s \n %s, %s %s", m.(*Location).Street, m.(*Location).City, m.(*Location).State, m.(*Location).Zip)
    case *Name:
        return fmt.Sprintf("%s. %s %s", m.(*Name).Title, m.(*Name).First, m.(*Name).Last)
    }
    return "Not Applicable"
}

fmt.Println(Merge(Location))

我从我的
PrintLn
收到了“
不适用”消息。在一个版本的代码中,我相信消息是“
超出了索引”

在您的示例中,您试图将结构本身传递给函数,而不是结构的实例。当我运行你的代码时,它不会编译。不过,我同意上面的评论,通过确保每个结构满足fmt.Stringer接口,这将得到更好的处理

代码的固定版本:

package main

import "fmt"

type Name struct {
    Title string
    First string
    Last  string
}

type Location struct {
    Street string
    City   string
    State  string
    Zip    string
}

func Merge(m interface{}) string {
    switch m.(type) {
    case Location:
        return fmt.Sprintf("%s \n %s, %s %s", m.(Location).Street, m.(Location).City, m.(Location).State, m.(Location).Zip)
    case Name:
        return fmt.Sprintf("%s. %s %s", m.(Name).Title, m.(Name).First, m.(Name).Last)
    }
    return "Not Applicable"
}

func main() {
    l := Location{
        Street: "122 Broadway",
        City: "New York",
        State: "NY",
        Zip: "1000",
    }
    fmt.Println(Merge(l))
}
使用fmt.String的版本:

package main

import "fmt"

type Name struct {
    Title string
    First string
    Last  string
}

func (n *Name) String() string {
    return fmt.Sprintf("%s. %s %s", n.Title, n.First, n.Last)
}

type Location struct {
    Street string
    City   string
    State  string
    Zip    string
}

func (l *Location) String() string {
    return fmt.Sprintf("%s \n %s, %s %s", l.Street, l.City, l.State, l.Zip)
}

func main() {
    l := &Location{
        Street: "120 Broadway",
        City:   "New York",
        State:  "NY",
        Zip:    "1000",
    }
    fmt.Println(l)

    n := &Name{
        Title: "Mr",
        First: "Billy",
        Last:  "Bob",
    }
    fmt.Println(n)
}

您没有将
*位置
传递到
合并
;这就是为什么你会得到“不适用”。此外,您可能需要考虑仅仅为您的类型实现。谢谢您的建议,提姆。你能详细说明我将如何使用fmt.Stringer吗?println(merge())行是我所拥有内容的简化。我的实际行是fmt.Println(Merge(servicesA.Users[0].Location))
servicesA.Users[0].Location的类型是什么?另外,您可能会发现
%v
%+v
Sprintf
一起使用非常有用,谢谢您的评论,克斯特亚。应该只是位置问题。当我尝试删除函数(*Location to Location)中的指针并运行它时,我得到了以下结果:panic:interface conversion:interface is main.Location not*main.Location谢谢你,Tom!这是一个很好的解释!当我键入Println函数时,我还忘了在合并函数中包含对*位置的&reference。我的最后一个Println方法是:fmt.Println(Merge(&servicesA.Users[0].Location])在更改并检查代码之后,它按照我的预期工作。再次感谢你,Tom。如果你要使用类型开关,你不应该在case body中使用类型断言。例如,OP提到的示例是一个简化,如果您有多个类型都希望有一个共同的行为,那么使用接口是很常见的(
fmt.Stringer
仅适用于整个类型的字符串表示)。例如,可能是这样的