Функция для несколькых структур
Есть 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 шт):
Так как предложенные вами структуры не имеют ничего общего, то наиболее подходящий тип, который может включать значения обоих типов, будет 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.