Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang switch between structs

I'm new to golang and I'm trying to create a function that, based on the struct it's used on, will return a formatted string using 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))

I'm getting the "Not Applicable" message from my PrintLn. In one version of the code, I believe the message was "out of index".

like image 570
Scott S. Avatar asked Mar 16 '23 17:03

Scott S.


1 Answers

In your example you are trying to pass the struct itself to the function rather than an instance of the struct. When I ran your code it wouldn't compile. I agree with the comments above though, this would be much better handled by making sure each struct satisfies the fmt.Stringer interface.

fmt.Stringer interface

A fixed version of your code:

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))
}

A version using 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)
}
like image 186
Tom Jowitt Avatar answered Mar 25 '23 05:03

Tom Jowitt