Функция для несколькых структур

Есть 2 структуры для примера (они должны быть больше)

    type One struct {
    A string
    b int
    }

    type Two struct {
    C float64
    D bool
    }

Нужно создать метод которы может принять и объект One и объект Two что то вроде этого

func foo(obj SomeTipe)  {
// ....
}

если память не изменяет например в Java можно создать один класс потом экстендить этот класс и вместо SomeTipe написать имя этого класса подскажите пожалуйста как можно это реализовать в Golang


Ответы (1 шт):

Автор решения: Pak Uula

Так как предложенные вами структуры не имеют ничего общего, то наиболее подходящий тип, который может включать значения обоих типов, будет interface{}.

В Golang есть специальная конструкция приведения типов: val, ok := obj.(T)

Упрощённо это работает так. Если истинный тип объекта obj равен T, то в переменную val будет записано значение типа T, а переменная ok будет равна true. Если же в obj находится объект другого типа, то значение val останется неопределённым, а значение ok будет равно false.

Соответвественно, код может быть таким:

package main

import (
    "fmt"
    "reflect"
)

type One struct {
    A string
    B int
}

type Two struct {
    C float64
    D bool
}

func foo_One(obj One) error {
    // Handler for One
    fmt.Printf("One{A: \"%s\", B: %v}", obj.A, obj.B)
    return nil
}

func foo_Two(obj Two) error {
    // Handler for Two
    fmt.Printf("Two{C: %f, D: %v}", obj.C, obj.D)
    return nil
}

func foo(obj interface{}) error {
    if one, ok := obj.(One); ok {
        return foo_One(one)
    }
    if two, ok := obj.(Two); ok {
        return foo_Two(two)
    }
    return fmt.Errorf("Invalid object type, expected %v or %v, got %v",
        reflect.TypeOf(One{}), reflect.TypeOf(Two{}), reflect.TypeOf(obj),
    )
}

func main() {
    err := foo(One{A: "Hello", B: 10})
    if err != nil {
        fmt.Printf("foo failed: %s\n", err.Error())
    }
    println()
    err = foo(Two{C: 1.2345, D: true})
    if err != nil {
        fmt.Printf("foo failed: %s\n", err.Error())
    }
    println()
    err = foo("A string")
    if err != nil {
        fmt.Printf("foo failed: %s\n", err.Error())
    }
    println()
}

Результат работы программы:

One{A: "Hello", B: 10}
Two{C: 1.234500, D: true}
foo failed: Invalid object type, expected main.One or main.Two, got string

Почему функция foo у меня возвращает error. Это сложившаяся практика программирования Go: если в функции что-то может пойти не так, то функция должна возвращать, помимо прочих, значение типа error.

→ Ссылка